Skip to content

Commit

Permalink
c++: Implement P1467R9 - Extended floating-point types and standard n…
Browse files Browse the repository at this point in the history
…ames compiler part except for bfloat16 [PR106652]

The following patch implements the compiler part of C++23
P1467R9 - Extended floating-point types and standard names compiler part
by introducing _Float{16,32,64,128} as keywords and builtin types
like they are implemented for C already since GCC 7, with DF{16,32,64,128}_
mangling.
It also introduces _Float{32,64,128}x for C++ with the
itanium-cxx-abi/cxx-abi#147
proposed mangling of DF{32,64,128}x.
The patch doesn't add anything for bfloat16_t support, as right now
__bf16 type refuses all conversions and arithmetic operations.
The patch wants to keep backwards compatibility with how __float128 has
been handled in C++ before, both for mangling and behavior in binary
operations, overload resolution etc.  So, there are some backend changes
where for C __float128 and _Float128 are the same type (float128_type_node
and float128t_type_node are the same pointer), but for C++ they are distinct
types which mangle differently and _Float128 is treated as extended
floating-point type while __float128 is treated as non-standard floating
point type.  The various C++23 changes about how floating-point types
are changed are actually implemented as written in the spec only if at least
one of the types involved is _Float{16,32,64,128,32x,64x,128x} (_FloatNx are
also treated as extended floating-point types) and kept previous behavior
otherwise.  For float/double/long double the rules are actually written that
they behave the same as before.
There is some backwards incompatibility at least on x86 regarding _Float16,
because that type was already used by that name and with the DF16_ mangling
(but only since GCC 12 and I think it isn't that widely used in the wild
yet).  E.g. config/i386/avx512fp16intrin.h shows the issues, where
in C or in GCC 12 in C++ one could pass 0.0f to a builtin taking _Float16
argument, but with the changes that is not possible anymore, one needs
to either use 0.0f16 or (_Float16) 0.0f.
We have also a problem with glibc headers, where since glibc 2.27
math.h and complex.h aren't compilable with these changes.  One gets
errors like:
In file included from /usr/include/math.h:43,
                 from abc.c:1:
/usr/include/bits/floatn.h:86:9: error: multiple types in one declaration
   86 | typedef __float128 _Float128;
      |         ^~~~~~~~~~
/usr/include/bits/floatn.h:86:20: error: declaration does not declare anything [-fpermissive]
   86 | typedef __float128 _Float128;
      |                    ^~~~~~~~~
In file included from /usr/include/bits/floatn.h:119:
/usr/include/bits/floatn-common.h:214:9: error: multiple types in one declaration
  214 | typedef float _Float32;
      |         ^~~~~
/usr/include/bits/floatn-common.h:214:15: error: declaration does not declare anything [-fpermissive]
  214 | typedef float _Float32;
      |               ^~~~~~~~
/usr/include/bits/floatn-common.h:251:9: error: multiple types in one declaration
  251 | typedef double _Float64;
      |         ^~~~~~
/usr/include/bits/floatn-common.h:251:16: error: declaration does not declare anything [-fpermissive]
  251 | typedef double _Float64;
      |                ^~~~~~~~
This is from snippets like:
 /* The remaining of this file provides support for older compilers.  */
 # if __HAVE_FLOAT128

 /* The type _Float128 exists only since GCC 7.0.  */
 #  if !__GNUC_PREREQ (7, 0) || defined __cplusplus
 typedef __float128 _Float128;
 #  endif
where it hardcodes that C++ doesn't have _Float{16,32,64,128,32x,64x,128x} support nor
{f,F}{16,32,64,128}{,x} literal suffixes nor _Complex _Float{16,32,64,128,32x,64x,128x}.
The patch fixincludes this for now and hopefully if this is committed, then
glibc can change those.  The patch changes those
 #  if !__GNUC_PREREQ (7, 0) || defined __cplusplus
conditions to
 #  if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
Another thing is mangling, as said above, Itanium C++ ABI specifies
DF <number> _ as _Float{16,32,64,128} mangling, but GCC was implementing
a mangling incompatible with that starting with DF for fixed point types.
Fixed point was never supported in C++ though, I believe the reason why
the mangling has been added was that due to a bug it would leak into the
C++ FE through decltype (0.0r) etc.  But that has been shortly after the
mangling was added fixed (I think in the same GCC release cycle), so we
now reject 0.0r etc. in C++.  If we ever need the fixed point mangling,
I think it can be readded but better with a different prefix so that it
doesn't conflict with the published standard manglings.  So, this patch
also kills the fixed point mangling and implements the DF <number> _
demangling.
The patch predefines __STDCPP_FLOAT{16,32,64,128}_T__ macros when
those types are available, but only for C++23, while the underlying types
are available in C++98 and later including the {f,F}{16,32,64,128} literal
suffixes (but those with a pedwarn for C++20 and earlier).  My understanding
is that it needs to be predefined by the compiler, on the other side
predefining even for older modes when <stdfloat> is a new C++23 header
would be weird.  One can find out if _Float{16,32,64,128,32x,64x,128x} is
supported in C++ by
__GNUC__ >= 13 && defined(__FLT{16,32,64,128,32X,64X,128X}_MANT_DIG__)
(but that doesn't work well with older G++ 13 snapshots).

As for std::bfloat16_t, three targets (aarch64, arm and x86) apparently
"support" __bf16 type which has the bfloat16 format, but isn't really
usable, e.g. {aarch64,arm,ix86}_invalid_conversion disallow any conversions
from or to type with BFmode, {aarch64,arm,ix86}_invalid_unary_op disallows
any unary operations on those except for ADDR_EXPR and
{aarch64,arm,ix86}_invalid_binary_op disallows any binary operation on
those.  So, I think we satisfy:
"If the implementation supports an extended floating-point type with the
properties, as specified by ISO/IEC/IEEE 60559, of radix (b) of 2, storage
width in bits (k) of 16, precision in bits (p) of 8, maximum exponent (emax)
of 127, and exponent field width in bits (w) of 8, then the typedef-name
std::bfloat16_t is defined in the header <stdfloat> and names such a type,
the macro __STDCPP_BFLOAT16_T__ is defined, and the floating-point literal
suffixes bf16 and BF16 are supported."
because we don't really support those right now.

2022-09-27  Jakub Jelinek  <[email protected]>

	PR c++/106652
	PR c++/85518
gcc/
	* tree-core.h (enum tree_index): Add TI_FLOAT128T_TYPE
	enumerator.
	* tree.h (float128t_type_node): Define.
	* tree.cc (build_common_tree_nodes): Initialize float128t_type_node.
	* builtins.def (DEF_FLOATN_BUILTIN): Adjust comment now that
	_Float<N> is supported in C++ too.
	* config/i386/i386.cc (ix86_mangle_type): Only mangle as "g"
	float128t_type_node.
	* config/i386/i386-builtins.cc (ix86_init_builtin_types): Use
	float128t_type_node for __float128 instead of float128_type_node
	and create it if NULL.
	* config/i386/avx512fp16intrin.h (_mm_setzero_ph, _mm256_setzero_ph,
	_mm512_setzero_ph, _mm_set_sh, _mm_load_sh): Use 0.0f16 instead of
	0.0f.
	* config/ia64/ia64.cc (ia64_init_builtins): Use
	float128t_type_node for __float128 instead of float128_type_node
	and create it if NULL.
	* config/rs6000/rs6000-c.cc (is_float128_p): Also return true
	for float128t_type_node if non-NULL.
	* config/rs6000/rs6000.cc (rs6000_mangle_type): Don't mangle
	float128_type_node as "u9__ieee128".
	* config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Use
	float128t_type_node for __float128 instead of float128_type_node
	and create it if NULL.
gcc/c-family/
	* c-common.cc (c_common_reswords): Change _Float{16,32,64,128} and
	_Float{32,64,128}x flags from D_CONLY to 0.
	(shorten_binary_op): Punt if common_type returns error_mark_node.
	(shorten_compare): Likewise.
	(c_common_nodes_and_builtins): For C++ record _Float{16,32,64,128}
	and _Float{32,64,128}x builtin types if available.  For C++
	clear float128t_type_node.
	* c-cppbuiltin.cc (c_cpp_builtins): Predefine
	__STDCPP_FLOAT{16,32,64,128}_T__ for C++23 if supported.
	* c-lex.cc (interpret_float): For q/Q suffixes prefer
	float128t_type_node over float128_type_node.  Allow
	{f,F}{16,32,64,128} suffixes for C++ if supported with pedwarn
	for C++20 and older.  Allow {f,F}{32,64,128}x suffixes for C++
	with pedwarn.  Don't call excess_precision_type for C++.
gcc/cp/
	* cp-tree.h (cp_compare_floating_point_conversion_ranks): Implement
	P1467R9 - Extended floating-point types and standard names except
	for std::bfloat16_t for now.  Declare.
	(extended_float_type_p): New inline function.
	* mangle.cc (write_builtin_type): Mangle float{16,32,64,128}_type_node
	as DF{16,32,64,128}_.  Mangle float{32,64,128}x_type_node as
	DF{32,64,128}x.  Remove FIXED_POINT_TYPE mangling that conflicts
	with that.
	* typeck2.cc (check_narrowing): If one of ftype or type is extended
	floating-point type, compare floating-point conversion ranks.
	* parser.cc (cp_keyword_starts_decl_specifier_p): Handle
	CASE_RID_FLOATN_NX.
	(cp_parser_simple_type_specifier): Likewise and diagnose missing
	_Float<N> or _Float<N>x support if not supported by target.
	* typeck.cc (cp_compare_floating_point_conversion_ranks): New function.
	(cp_common_type): If both types are REAL_TYPE and one or both are
	extended floating-point types, select common type based on comparison
	of floating-point conversion ranks and subranks.
	(cp_build_binary_op): Diagnose operation with floating point arguments
	with unordered conversion ranks.
	* call.cc (standard_conversion): For floating-point conversion, if
	either from or to are extended floating-point types, set conv->bad_p
	for implicit conversion from larger to smaller conversion rank or
	with unordered conversion ranks.
	(convert_like_internal): Emit a pedwarn on such conversions.
	(build_conditional_expr): Diagnose operation with floating point
	arguments with unordered conversion ranks.
	(convert_arg_to_ellipsis): Don't promote extended floating-point types
	narrower than double to double.
	(compare_ics): Implement P1467R9 [over.ics.rank]/4 changes.
gcc/testsuite/
	* g++.dg/cpp23/ext-floating1.C: New test.
	* g++.dg/cpp23/ext-floating2.C: New test.
	* g++.dg/cpp23/ext-floating3.C: New test.
	* g++.dg/cpp23/ext-floating4.C: New test.
	* g++.dg/cpp23/ext-floating5.C: New test.
	* g++.dg/cpp23/ext-floating6.C: New test.
	* g++.dg/cpp23/ext-floating7.C: New test.
	* g++.dg/cpp23/ext-floating8.C: New test.
	* g++.dg/cpp23/ext-floating9.C: New test.
	* g++.dg/cpp23/ext-floating10.C: New test.
	* g++.dg/cpp23/ext-floating.h: New file.
	* g++.target/i386/float16-1.C: Adjust expected diagnostics.
libcpp/
	* expr.cc (interpret_float_suffix): Allow {f,F}{16,32,64,128} and
	{f,F}{32,64,128}x suffixes for C++.
include/
	* demangle.h (enum demangle_component_type): Add
	DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE.
	(struct demangle_component): Add u.s_extended_builtin member.
libiberty/
	* cp-demangle.c (d_dump): Handle
	DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE.  Don't handle
	DEMANGLE_COMPONENT_FIXED_TYPE.
	(d_make_extended_builtin_type): New function.
	(cplus_demangle_builtin_types): Add _Float entry.
	(cplus_demangle_type): For DF demangle it as _Float<N> or
	_Float<N>x rather than fixed point which conflicts with it.
	(d_count_templates_scopes): Handle
	DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE.  Just break; for
	DEMANGLE_COMPONENT_FIXED_TYPE.
	(d_find_pack): Handle DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE.
	Don't handle DEMANGLE_COMPONENT_FIXED_TYPE.
	(d_print_comp_inner): Likewise.
	* cp-demangle.h (D_BUILTIN_TYPE_COUNT): Bump.
	* testsuite/demangle-expected: Replace _Z3xxxDFyuVb test
	with _Z3xxxDF16_DF32_DF64_DF128_CDF16_Vb.  Add
	_Z3xxxDF32xDF64xDF128xCDF32xVb test.
fixincludes/
	* inclhack.def (glibc_cxx_floatn_1, glibc_cxx_floatn_2,
	glibc_cxx_floatn_3): New fixes.
	* tests/base/bits/floatn.h: New file.
	* fixincl.x: Regenerated.
  • Loading branch information
jakubjelinek committed Sep 27, 2022
1 parent 8be6564 commit b042088
Show file tree
Hide file tree
Showing 40 changed files with 1,974 additions and 148 deletions.
154 changes: 149 additions & 5 deletions fixincludes/fixincl.x
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
*
* DO NOT EDIT THIS FILE (fixincl.x)
*
* It has been AutoGen-ed February 27, 2022 at 07:47:03 PM by AutoGen 5.18.16
* It has been AutoGen-ed September 27, 2022 at 12:49:21 AM by AutoGen 5.18.16
* From the definitions inclhack.def
* and the template file fixincl
*/
/* DO NOT SVN-MERGE THIS FILE, EITHER Sun Feb 27 19:47:03 UTC 2022
/* DO NOT SVN-MERGE THIS FILE, EITHER Tue Sep 27 00:49:21 CEST 2022
*
* You must regenerate it. Use the ./genfixes script.
*
Expand All @@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
* This file contains 267 fixup descriptions.
* This file contains 270 fixup descriptions.
*
* See README for more information.
*
Expand Down Expand Up @@ -4105,6 +4105,132 @@ static const char* apzGlibc_C99_Inline_4Patch[] = {
"%0 __attribute__ ((__gnu_inline__))",
(char*)NULL };

/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Description of Glibc_Cxx_Floatn_1 fix
*/
tSCC zGlibc_Cxx_Floatn_1Name[] =
"glibc_cxx_floatn_1";

/*
* File name selection pattern
*/
tSCC zGlibc_Cxx_Floatn_1List[] =
"bits/floatn.h\0bits/floatn-common.h\0";
/*
* Machine/OS name selection pattern
*/
#define apzGlibc_Cxx_Floatn_1Machs (const char**)NULL

/*
* content selection pattern - do fix if pattern found
*/
tSCC zGlibc_Cxx_Floatn_1Select0[] =
"^([ \t]*#[ \t]*if !__GNUC_PREREQ \\(7, 0\\) \\|\\| )defined __cplusplus\n\
(([ \t]*/\\*[^\n\
]*\\*/\n\
)?([ \t]*#[ \t]*if[^\n\
]*\n\
)?[ \t]*#[ \t]*define __f(16|32|64|128)x?\\()";

#define GLIBC_CXX_FLOATN_1_TEST_CT 1
static tTestDesc aGlibc_Cxx_Floatn_1Tests[] = {
{ TT_EGREP, zGlibc_Cxx_Floatn_1Select0, (regex_t*)NULL }, };

/*
* Fix Command Arguments for Glibc_Cxx_Floatn_1
*/
static const char* apzGlibc_Cxx_Floatn_1Patch[] = {
"format",
"%1(defined __cplusplus && !__GNUC_PREREQ (13, 0))\n\
%2",
(char*)NULL };

/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Description of Glibc_Cxx_Floatn_2 fix
*/
tSCC zGlibc_Cxx_Floatn_2Name[] =
"glibc_cxx_floatn_2";

/*
* File name selection pattern
*/
tSCC zGlibc_Cxx_Floatn_2List[] =
"bits/floatn.h\0bits/floatn-common.h\0";
/*
* Machine/OS name selection pattern
*/
#define apzGlibc_Cxx_Floatn_2Machs (const char**)NULL

/*
* content selection pattern - do fix if pattern found
*/
tSCC zGlibc_Cxx_Floatn_2Select0[] =
"^([ \t]*#[ \t]*if !__GNUC_PREREQ \\(7, 0\\) \\|\\| )defined __cplusplus\n\
(([ \t]*/\\*[^\n\
]*\\*/\n\
)?[ \t]*typedef[ \t]+[^\n\
]*[ \t]+_Float(16|32|64|128)x?([ \t]+__attribute__ \\(\\(__mode__ \\(__HF__\\)\\)\\))?;)";

#define GLIBC_CXX_FLOATN_2_TEST_CT 1
static tTestDesc aGlibc_Cxx_Floatn_2Tests[] = {
{ TT_EGREP, zGlibc_Cxx_Floatn_2Select0, (regex_t*)NULL }, };

/*
* Fix Command Arguments for Glibc_Cxx_Floatn_2
*/
static const char* apzGlibc_Cxx_Floatn_2Patch[] = {
"format",
"%1(defined __cplusplus && !__GNUC_PREREQ (13, 0))\n\
%2",
(char*)NULL };

/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Description of Glibc_Cxx_Floatn_3 fix
*/
tSCC zGlibc_Cxx_Floatn_3Name[] =
"glibc_cxx_floatn_3";

/*
* File name selection pattern
*/
tSCC zGlibc_Cxx_Floatn_3List[] =
"bits/floatn.h\0bits/floatn-common.h\0";
/*
* Machine/OS name selection pattern
*/
#define apzGlibc_Cxx_Floatn_3Machs (const char**)NULL

/*
* content selection pattern - do fix if pattern found
*/
tSCC zGlibc_Cxx_Floatn_3Select0[] =
"^([ \t]*#[ \t]*if !__GNUC_PREREQ \\(7, 0\\) \\|\\| )defined __cplusplus\n\
(([ \t]*/\\*[^\n\
]*\n\
?[^\n\
]*\\*/\n\
)?([ \t]*#[ \t]*if[^\n\
]*\n\
)?([ \t]*typedef[ \t]+[^\n\
]*;\n\
)?[ \t]*#[ \t]*define __CFLOAT(16|32|64|128)X?[ \t]+)";

#define GLIBC_CXX_FLOATN_3_TEST_CT 1
static tTestDesc aGlibc_Cxx_Floatn_3Tests[] = {
{ TT_EGREP, zGlibc_Cxx_Floatn_3Select0, (regex_t*)NULL }, };

/*
* Fix Command Arguments for Glibc_Cxx_Floatn_3
*/
static const char* apzGlibc_Cxx_Floatn_3Patch[] = {
"format",
"%1(defined __cplusplus && !__GNUC_PREREQ (13, 0))\n\
%2",
(char*)NULL };

/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Description of Glibc_Mutex_Init fix
Expand Down Expand Up @@ -10872,9 +10998,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
#define REGEX_COUNT 305
#define REGEX_COUNT 308
#define MACH_LIST_SIZE_LIMIT 187
#define FIX_COUNT 267
#define FIX_COUNT 270

/*
* Enumerate the fixes
Expand Down Expand Up @@ -10977,6 +11103,9 @@ typedef enum {
GLIBC_C99_INLINE_2_FIXIDX,
GLIBC_C99_INLINE_3_FIXIDX,
GLIBC_C99_INLINE_4_FIXIDX,
GLIBC_CXX_FLOATN_1_FIXIDX,
GLIBC_CXX_FLOATN_2_FIXIDX,
GLIBC_CXX_FLOATN_3_FIXIDX,
GLIBC_MUTEX_INIT_FIXIDX,
GLIBC_STDINT_FIXIDX,
GLIBC_STRNCPY_FIXIDX,
Expand Down Expand Up @@ -11635,6 +11764,21 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
GLIBC_C99_INLINE_4_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aGlibc_C99_Inline_4Tests, apzGlibc_C99_Inline_4Patch, 0 },

{ zGlibc_Cxx_Floatn_1Name, zGlibc_Cxx_Floatn_1List,
apzGlibc_Cxx_Floatn_1Machs,
GLIBC_CXX_FLOATN_1_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aGlibc_Cxx_Floatn_1Tests, apzGlibc_Cxx_Floatn_1Patch, 0 },

{ zGlibc_Cxx_Floatn_2Name, zGlibc_Cxx_Floatn_2List,
apzGlibc_Cxx_Floatn_2Machs,
GLIBC_CXX_FLOATN_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aGlibc_Cxx_Floatn_2Tests, apzGlibc_Cxx_Floatn_2Patch, 0 },

{ zGlibc_Cxx_Floatn_3Name, zGlibc_Cxx_Floatn_3List,
apzGlibc_Cxx_Floatn_3Machs,
GLIBC_CXX_FLOATN_3_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aGlibc_Cxx_Floatn_3Tests, apzGlibc_Cxx_Floatn_3Patch, 0 },

{ zGlibc_Mutex_InitName, zGlibc_Mutex_InitList,
apzGlibc_Mutex_InitMachs,
GLIBC_MUTEX_INIT_TEST_CT, FD_MACH_ONLY,
Expand Down
96 changes: 96 additions & 0 deletions fixincludes/inclhack.def
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,102 @@ fix = {
EOT;
};

/* glibc-2.27 to 2.36 assume GCC 7 or later supports some or all
* of _Float{16,32,64,128} and _Float{32,64,128}x keywords for C,
* but doesn't for C++.
*/
fix = {
hackname = glibc_cxx_floatn_1;
files = bits/floatn.h, bits/floatn-common.h;
select = "^([ \t]*#[ \t]*if !__GNUC_PREREQ \\(7, 0\\) \\|\\| )defined __cplusplus\n"
"(([ \t]*/\\*[^\n]*\\*/\n)?"
"([ \t]*#[ \t]*if[^\n]*\n)?"
"[ \t]*#[ \t]*define __f(16|32|64|128)x?\\()";
c_fix = format;
c_fix_arg = "%1(defined __cplusplus && !__GNUC_PREREQ (13, 0))\n%2";
test_text = <<-EOT
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* The literal suffix f128 exists only since GCC 7.0. */
# define __f128(x) x##l
# else
# define __f128(x) x##f128
# endif
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* The literal suffix (f128) exist for powerpc only since GCC 7.0. */
# if __LDBL_MANT_DIG__ == 113
# define __f128(x) x##l
# else
# define __f128(x) x##q
# endif
# else
# define __f128(x) x##f128
# endif
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# ifdef __NO_LONG_DOUBLE_MATH
# define __f64(x) x##l
# else
# define __f64(x) x
# endif
# else
# define __f64(x) x##f64
# endif
EOT;
};

fix = {
hackname = glibc_cxx_floatn_2;
files = bits/floatn.h, bits/floatn-common.h;
select = "^([ \t]*#[ \t]*if !__GNUC_PREREQ \\(7, 0\\) \\|\\| )defined __cplusplus\n"
"(([ \t]*/\\*[^\n]*\\*/\n)?"
"[ \t]*typedef[ \t]+[^\n]*[ \t]+_Float(16|32|64|128)x?([ \t]+__attribute__ \\(\\(__mode__ \\(__HF__\\)\\)\\))?;)";
c_fix = format;
c_fix_arg = "%1(defined __cplusplus && !__GNUC_PREREQ (13, 0))\n%2";
test_text = <<-EOT
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef float _Float16 __attribute__ ((__mode__ (__HF__)));
# endif
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef __float128 _Float128;
# endif
EOT;
};

fix = {
hackname = glibc_cxx_floatn_3;
files = bits/floatn.h, bits/floatn-common.h;
select = "^([ \t]*#[ \t]*if !__GNUC_PREREQ \\(7, 0\\) \\|\\| )defined __cplusplus\n"
"(([ \t]*/\\*[^\n]*\n?[^\n]*\\*/\n)?"
"([ \t]*#[ \t]*if[^\n]*\n)?"
"([ \t]*typedef[ \t]+[^\n]*;\n)?"
"[ \t]*#[ \t]*define __CFLOAT(16|32|64|128)X?[ \t]+)";
c_fix = format;
c_fix_arg = "%1(defined __cplusplus && !__GNUC_PREREQ (13, 0))\n%2";
test_text = <<-EOT
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# define __CFLOAT128 _Complex long double
# else
# define __CFLOAT128 _Complex _Float128
# endif
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* Add a typedef for older GCC compilers which don't natively support
_Complex _Float128. */
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
# define __CFLOAT128 __cfloat128
# else
# define __CFLOAT128 _Complex _Float128
# endif
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# ifdef __NO_LONG_DOUBLE_MATH
# define __CFLOAT64 _Complex long double
# else
# define __CFLOAT64 _Complex double
# endif
# else
# define __CFLOAT64 _Complex _Float64
# endif
EOT;
};

/* glibc-2.3.5 defines pthread mutex initializers incorrectly,
* so we replace them with versions that correspond to the
* definition.
Expand Down
74 changes: 74 additions & 0 deletions fixincludes/tests/base/bits/floatn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* DO NOT EDIT THIS FILE.
It has been auto-edited by fixincludes from:
"fixinc/tests/inc/bits/floatn.h"
This had to be done to correct non-standard usages in the
original, manufacturer supplied header file. */



#if defined( GLIBC_CXX_FLOATN_1_CHECK )
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
/* The literal suffix f128 exists only since GCC 7.0. */
# define __f128(x) x##l
# else
# define __f128(x) x##f128
# endif
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
/* The literal suffix (f128) exist for powerpc only since GCC 7.0. */
# if __LDBL_MANT_DIG__ == 113
# define __f128(x) x##l
# else
# define __f128(x) x##q
# endif
# else
# define __f128(x) x##f128
# endif
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
# ifdef __NO_LONG_DOUBLE_MATH
# define __f64(x) x##l
# else
# define __f64(x) x
# endif
# else
# define __f64(x) x##f64
# endif
#endif /* GLIBC_CXX_FLOATN_1_CHECK */


#if defined( GLIBC_CXX_FLOATN_2_CHECK )
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
typedef float _Float16 __attribute__ ((__mode__ (__HF__)));
# endif
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
typedef __float128 _Float128;
# endif
#endif /* GLIBC_CXX_FLOATN_2_CHECK */


#if defined( GLIBC_CXX_FLOATN_3_CHECK )
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
# define __CFLOAT128 _Complex long double
# else
# define __CFLOAT128 _Complex _Float128
# endif
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
/* Add a typedef for older GCC compilers which don't natively support
_Complex _Float128. */
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
# define __CFLOAT128 __cfloat128
# else
# define __CFLOAT128 _Complex _Float128
# endif
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
# ifdef __NO_LONG_DOUBLE_MATH
# define __CFLOAT64 _Complex long double
# else
# define __CFLOAT64 _Complex double
# endif
# else
# define __CFLOAT64 _Complex _Float64
# endif
#endif /* GLIBC_CXX_FLOATN_3_CHECK */
5 changes: 2 additions & 3 deletions gcc/builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,8 @@ along with GCC; see the file COPYING3. If not see
with an argument such as FLOAT32 to produce the enum value for the type. If
we are compiling for the C language with GNU extensions, we enable the name
without the __builtin_ prefix as well as the name with the __builtin_
prefix. C++ does not enable these names by default because they don't have
the _Float<N> and _Float<N>X keywords, and a class based library should use
the __builtin_ names. */
prefix. C++ does not enable these names by default because a class based
library should use the __builtin_ names. */
#undef DEF_FLOATN_BUILTIN
#define DEF_FLOATN_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
Expand Down
Loading

0 comments on commit b042088

Please sign in to comment.