aboutsummaryrefslogtreecommitdiff
path: root/math
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2017-08-02 16:09:01 +0000
committerJoseph Myers <joseph@codesourcery.com>2017-08-02 16:09:01 +0000
commit2fee621de0776a6e729c3b18c27442e00733f2b2 (patch)
tree177de86dc69d58d34beab8a80799ae91c26f3bfd /math
parentb358255f953943967398e19066eb266c6ea881b9 (diff)
downloadglibc-2fee621de0776a6e729c3b18c27442e00733f2b2.tar
glibc-2fee621de0776a6e729c3b18c27442e00733f2b2.tar.gz
glibc-2fee621de0776a6e729c3b18c27442e00733f2b2.tar.bz2
glibc-2fee621de0776a6e729c3b18c27442e00733f2b2.zip
Fix tgmath.h for bit-fields (bug 21685).
The tgmath.h macros produce errors for bit-field arguments, because they apply sizeof and typeof to the arguments. This patch fixes them to use unary + systematically before using sizeof or typeof on arguments that might be bit-fields (note that __real__ of a bit-field is still a bit-field for this purpose, since it's an lvalue). gen-tgmath-tests.py is extended to add tests for this case. Tested for x86_64. [BZ #21685] * math/tgmath.h (__tgmath_real_type): Use unary + on potentially bit-field expressions passed to sizeof or typeof. [__HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)] (__TGMATH_F128): Likewise. [__HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)] (__TGMATH_CF128): Likewise. (__TGMATH_UNARY_REAL_ONLY): Likewise. (__TGMATH_UNARY_REAL_RET_ONLY): Likewise. (__TGMATH_BINARY_FIRST_REAL_ONLY): Likewise. (__TGMATH_BINARY_FIRST_REAL_STD_ONLY): Likewise. (__TGMATH_BINARY_REAL_ONLY): Likewise. (__TGMATH_BINARY_REAL_STD_ONLY): Likewise. (__TGMATH_BINARY_REAL_RET_ONLY): Likewise. (__TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY): Likewise. (__TGMATH_TERNARY_REAL_ONLY): Likewise. (__TGMATH_TERNARY_FIRST_REAL_RET_ONLY): Likewise. (__TGMATH_UNARY_REAL_IMAG): Likewise. (__TGMATH_UNARY_IMAG): Likewise. (__TGMATH_UNARY_REAL_IMAG_RET_REAL): Likewise. (__TGMATH_BINARY_REAL_IMAG): Likewise. * math/gen-tgmath-tests.py (Type.init_types): Create bit_field type. (define_vars_for_type): Handle bit_field type specially. (Tests.__init__): Declare structure with bit-field element.
Diffstat (limited to 'math')
-rwxr-xr-xmath/gen-tgmath-tests.py12
-rw-r--r--math/tgmath.h118
2 files changed, 70 insertions, 60 deletions
diff --git a/math/gen-tgmath-tests.py b/math/gen-tgmath-tests.py
index 0c548ef9f9..e749e3d8b0 100755
--- a/math/gen-tgmath-tests.py
+++ b/math/gen-tgmath-tests.py
@@ -197,6 +197,7 @@ class Type(object):
Type.create_type('unsigned long long int', integer=True)
Type.create_type('enum e', integer=True, complex_ok=False)
Type.create_type('_Bool', integer=True, complex_ok=False)
+ Type.create_type('bit_field', integer=True, complex_ok=False)
# Internal types represent the combination of long double with
# _Float64 or _Float64x, for which the ordering depends on
# whether long double has the same format as double.
@@ -273,6 +274,11 @@ def vol_var_for_type(name):
def define_vars_for_type(name):
"""Return the definitions of variables with a given type (name)."""
+ if name == 'bit_field':
+ struct_vars = define_vars_for_type('struct s');
+ return '%s#define %s %s.bf\n' % (struct_vars,
+ vol_var_for_type(name),
+ vol_var_for_type('struct s'))
return ('%s %s __attribute__ ((unused));\n'
'%s volatile %s __attribute__ ((unused));\n'
% (name, var_for_type(name), name, vol_var_for_type(name)))
@@ -311,7 +317,11 @@ class Tests(object):
'int num_pass, num_fail;\n'
'volatile int called_mant_dig;\n'
'const char *volatile called_func_name;\n'
- 'enum e { E, F };\n']
+ 'enum e { E, F };\n'
+ 'struct s\n'
+ ' {\n'
+ ' int bf:2;\n'
+ ' };\n']
float64_text = ('# if LDBL_MANT_DIG == DBL_MANT_DIG\n'
'typedef _Float64 long_double_Float64;\n'
'typedef __CFLOAT64 complex_long_double_Float64;\n'
diff --git a/math/tgmath.h b/math/tgmath.h
index f75e3dca78..211948c2e4 100644
--- a/math/tgmath.h
+++ b/math/tgmath.h
@@ -67,19 +67,19 @@
/* The tgmath real type of EXPR. */
# define __tgmath_real_type(expr) \
- __tgmath_real_type_sub (__typeof__ ((__typeof__ (expr)) 0), \
- __floating_type (__typeof__ (expr)))
+ __tgmath_real_type_sub (__typeof__ ((__typeof__ (+(expr))) 0), \
+ __floating_type (__typeof__ (+(expr))))
/* Expand to text that checks if ARG_COMB has type _Float128, and if
so calls the appropriately suffixed FCT (which may include a cast),
or FCT and CFCT for complex functions, with arguments ARG_CALL. */
# if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
# define __TGMATH_F128(arg_comb, fct, arg_call) \
- __builtin_types_compatible_p (__typeof (arg_comb), _Float128) \
+ __builtin_types_compatible_p (__typeof (+(arg_comb)), _Float128) \
? fct ## f128 arg_call :
# define __TGMATH_CF128(arg_comb, fct, cfct, arg_call) \
- __builtin_types_compatible_p (__typeof (__real__ (arg_comb)), _Float128) \
- ? (sizeof (__real__ (arg_comb)) == sizeof (arg_comb) \
+ __builtin_types_compatible_p (__typeof (+__real__ (arg_comb)), _Float128) \
+ ? (sizeof (+__real__ (arg_comb)) == sizeof (+(arg_comb)) \
? fct ## f128 arg_call \
: cfct ## f128 arg_call) :
# else
@@ -92,45 +92,45 @@
only defined on real valued parameters and those which are defined
for complex functions as well. */
# define __TGMATH_UNARY_REAL_ONLY(Val, Fct) \
- (__extension__ ((sizeof (Val) == sizeof (double) \
+ (__extension__ ((sizeof (+(Val)) == sizeof (double) \
|| __builtin_classify_type (Val) != 8) \
? (__tgmath_real_type (Val)) Fct (Val) \
- : (sizeof (Val) == sizeof (float)) \
+ : (sizeof (+(Val)) == sizeof (float)) \
? (__tgmath_real_type (Val)) Fct##f (Val) \
: __TGMATH_F128 ((Val), (__tgmath_real_type (Val)) Fct, \
(Val)) \
(__tgmath_real_type (Val)) __tgml(Fct) (Val)))
# define __TGMATH_UNARY_REAL_RET_ONLY(Val, Fct) \
- (__extension__ ((sizeof (Val) == sizeof (double) \
+ (__extension__ ((sizeof (+(Val)) == sizeof (double) \
|| __builtin_classify_type (Val) != 8) \
? Fct (Val) \
- : (sizeof (Val) == sizeof (float)) \
+ : (sizeof (+(Val)) == sizeof (float)) \
? Fct##f (Val) \
: __TGMATH_F128 ((Val), Fct, (Val)) \
__tgml(Fct) (Val)))
# define __TGMATH_BINARY_FIRST_REAL_ONLY(Val1, Val2, Fct) \
- (__extension__ ((sizeof (Val1) == sizeof (double) \
+ (__extension__ ((sizeof (+(Val1)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8) \
? (__tgmath_real_type (Val1)) Fct (Val1, Val2) \
- : (sizeof (Val1) == sizeof (float)) \
+ : (sizeof (+(Val1)) == sizeof (float)) \
? (__tgmath_real_type (Val1)) Fct##f (Val1, Val2) \
: __TGMATH_F128 ((Val1), (__tgmath_real_type (Val1)) Fct, \
(Val1, Val2)) \
(__tgmath_real_type (Val1)) __tgml(Fct) (Val1, Val2)))
# define __TGMATH_BINARY_FIRST_REAL_STD_ONLY(Val1, Val2, Fct) \
- (__extension__ ((sizeof (Val1) == sizeof (double) \
+ (__extension__ ((sizeof (+(Val1)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8) \
? (__tgmath_real_type (Val1)) Fct (Val1, Val2) \
- : (sizeof (Val1) == sizeof (float)) \
+ : (sizeof (+(Val1)) == sizeof (float)) \
? (__tgmath_real_type (Val1)) Fct##f (Val1, Val2) \
: (__tgmath_real_type (Val1)) __tgml(Fct) (Val1, Val2)))
# define __TGMATH_BINARY_REAL_ONLY(Val1, Val2, Fct) \
- (__extension__ (((sizeof (Val1) > sizeof (double) \
- || sizeof (Val2) > sizeof (double)) \
+ (__extension__ (((sizeof (+(Val1)) > sizeof (double) \
+ || sizeof (+(Val2)) > sizeof (double)) \
&& __builtin_classify_type ((Val1) + (Val2)) == 8) \
? __TGMATH_F128 ((Val1) + (Val2), \
(__typeof \
@@ -140,8 +140,8 @@
(__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
__tgml(Fct) (Val1, Val2) \
- : (sizeof (Val1) == sizeof (double) \
- || sizeof (Val2) == sizeof (double) \
+ : (sizeof (+(Val1)) == sizeof (double) \
+ || sizeof (+(Val2)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8 \
|| __builtin_classify_type (Val2) != 8) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
@@ -152,14 +152,14 @@
Fct##f (Val1, Val2)))
# define __TGMATH_BINARY_REAL_STD_ONLY(Val1, Val2, Fct) \
- (__extension__ (((sizeof (Val1) > sizeof (double) \
- || sizeof (Val2) > sizeof (double)) \
+ (__extension__ (((sizeof (+(Val1)) > sizeof (double) \
+ || sizeof (+(Val2)) > sizeof (double)) \
&& __builtin_classify_type ((Val1) + (Val2)) == 8) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
__tgml(Fct) (Val1, Val2) \
- : (sizeof (Val1) == sizeof (double) \
- || sizeof (Val2) == sizeof (double) \
+ : (sizeof (+(Val1)) == sizeof (double) \
+ || sizeof (+(Val2)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8 \
|| __builtin_classify_type (Val2) != 8) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
@@ -170,21 +170,21 @@
Fct##f (Val1, Val2)))
# define __TGMATH_BINARY_REAL_RET_ONLY(Val1, Val2, Fct) \
- (__extension__ (((sizeof (Val1) > sizeof (double) \
- || sizeof (Val2) > sizeof (double)) \
+ (__extension__ (((sizeof (+(Val1)) > sizeof (double) \
+ || sizeof (+(Val2)) > sizeof (double)) \
&& __builtin_classify_type ((Val1) + (Val2)) == 8) \
? __TGMATH_F128 ((Val1) + (Val2), Fct, (Val1, Val2)) \
__tgml(Fct) (Val1, Val2) \
- : (sizeof (Val1) == sizeof (double) \
- || sizeof (Val2) == sizeof (double) \
+ : (sizeof (+(Val1)) == sizeof (double) \
+ || sizeof (+(Val2)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8 \
|| __builtin_classify_type (Val2) != 8) \
? Fct (Val1, Val2) \
: Fct##f (Val1, Val2)))
# define __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY(Val1, Val2, Val3, Fct) \
- (__extension__ (((sizeof (Val1) > sizeof (double) \
- || sizeof (Val2) > sizeof (double)) \
+ (__extension__ (((sizeof (+(Val1)) > sizeof (double) \
+ || sizeof (+(Val2)) > sizeof (double)) \
&& __builtin_classify_type ((Val1) + (Val2)) == 8) \
? __TGMATH_F128 ((Val1) + (Val2), \
(__typeof \
@@ -194,8 +194,8 @@
(__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
__tgml(Fct) (Val1, Val2, Val3) \
- : (sizeof (Val1) == sizeof (double) \
- || sizeof (Val2) == sizeof (double) \
+ : (sizeof (+(Val1)) == sizeof (double) \
+ || sizeof (+(Val2)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8 \
|| __builtin_classify_type (Val2) != 8) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
@@ -206,9 +206,9 @@
Fct##f (Val1, Val2, Val3)))
# define __TGMATH_TERNARY_REAL_ONLY(Val1, Val2, Val3, Fct) \
- (__extension__ (((sizeof (Val1) > sizeof (double) \
- || sizeof (Val2) > sizeof (double) \
- || sizeof (Val3) > sizeof (double)) \
+ (__extension__ (((sizeof (+(Val1)) > sizeof (double) \
+ || sizeof (+(Val2)) > sizeof (double) \
+ || sizeof (+(Val3)) > sizeof (double)) \
&& __builtin_classify_type ((Val1) + (Val2) + (Val3)) \
== 8) \
? __TGMATH_F128 ((Val1) + (Val2) + (Val3), \
@@ -221,9 +221,9 @@
+ (__tgmath_real_type (Val2)) 0 \
+ (__tgmath_real_type (Val3)) 0)) \
__tgml(Fct) (Val1, Val2, Val3) \
- : (sizeof (Val1) == sizeof (double) \
- || sizeof (Val2) == sizeof (double) \
- || sizeof (Val3) == sizeof (double) \
+ : (sizeof (+(Val1)) == sizeof (double) \
+ || sizeof (+(Val2)) == sizeof (double) \
+ || sizeof (+(Val3)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8 \
|| __builtin_classify_type (Val2) != 8 \
|| __builtin_classify_type (Val3) != 8) \
@@ -237,10 +237,10 @@
Fct##f (Val1, Val2, Val3)))
# define __TGMATH_TERNARY_FIRST_REAL_RET_ONLY(Val1, Val2, Val3, Fct) \
- (__extension__ ((sizeof (Val1) == sizeof (double) \
+ (__extension__ ((sizeof (+(Val1)) == sizeof (double) \
|| __builtin_classify_type (Val1) != 8) \
? Fct (Val1, Val2, Val3) \
- : (sizeof (Val1) == sizeof (float)) \
+ : (sizeof (+(Val1)) == sizeof (float)) \
? Fct##f (Val1, Val2, Val3) \
: __TGMATH_F128 ((Val1), Fct, (Val1, Val2, Val3)) \
__tgml(Fct) (Val1, Val2, Val3)))
@@ -248,28 +248,28 @@
/* XXX This definition has to be changed as soon as the compiler understands
the imaginary keyword. */
# define __TGMATH_UNARY_REAL_IMAG(Val, Fct, Cfct) \
- (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \
+ (__extension__ ((sizeof (+__real__ (Val)) == sizeof (double) \
|| __builtin_classify_type (__real__ (Val)) != 8) \
- ? ((sizeof (__real__ (Val)) == sizeof (Val)) \
+ ? ((sizeof (+__real__ (Val)) == sizeof (+(Val))) \
? (__tgmath_real_type (Val)) Fct (Val) \
: (__tgmath_real_type (Val)) Cfct (Val)) \
- : (sizeof (__real__ (Val)) == sizeof (float)) \
- ? ((sizeof (__real__ (Val)) == sizeof (Val)) \
+ : (sizeof (+__real__ (Val)) == sizeof (float)) \
+ ? ((sizeof (+__real__ (Val)) == sizeof (+(Val))) \
? (__tgmath_real_type (Val)) Fct##f (Val) \
: (__tgmath_real_type (Val)) Cfct##f (Val)) \
: __TGMATH_CF128 ((Val), (__tgmath_real_type (Val)) Fct, \
(__tgmath_real_type (Val)) Cfct, \
(Val)) \
- ((sizeof (__real__ (Val)) == sizeof (Val)) \
+ ((sizeof (+__real__ (Val)) == sizeof (+(Val))) \
? (__tgmath_real_type (Val)) __tgml(Fct) (Val) \
: (__tgmath_real_type (Val)) __tgml(Cfct) (Val))))
# define __TGMATH_UNARY_IMAG(Val, Cfct) \
- (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \
+ (__extension__ ((sizeof (+__real__ (Val)) == sizeof (double) \
|| __builtin_classify_type (__real__ (Val)) != 8) \
? (__typeof__ ((__tgmath_real_type (Val)) 0 \
+ _Complex_I)) Cfct (Val) \
- : (sizeof (__real__ (Val)) == sizeof (float)) \
+ : (sizeof (+__real__ (Val)) == sizeof (float)) \
? (__typeof__ ((__tgmath_real_type (Val)) 0 \
+ _Complex_I)) Cfct##f (Val) \
: __TGMATH_F128 (__real__ (Val), \
@@ -282,15 +282,15 @@
/* XXX This definition has to be changed as soon as the compiler understands
the imaginary keyword. */
# define __TGMATH_UNARY_REAL_IMAG_RET_REAL(Val, Fct, Cfct) \
- (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \
+ (__extension__ ((sizeof (+__real__ (Val)) == sizeof (double) \
|| __builtin_classify_type (__real__ (Val)) != 8) \
- ? ((sizeof (__real__ (Val)) == sizeof (Val)) \
+ ? ((sizeof (+__real__ (Val)) == sizeof (+(Val))) \
? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\
Fct (Val) \
: (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\
Cfct (Val)) \
- : (sizeof (__real__ (Val)) == sizeof (float)) \
- ? ((sizeof (__real__ (Val)) == sizeof (Val)) \
+ : (sizeof (+__real__ (Val)) == sizeof (float)) \
+ ? ((sizeof (+__real__ (Val)) == sizeof (+(Val))) \
? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\
Fct##f (Val) \
: (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\
@@ -303,7 +303,7 @@
(__real__ \
(__tgmath_real_type (Val)) 0)) Cfct, \
(Val)) \
- ((sizeof (__real__ (Val)) == sizeof (Val)) \
+ ((sizeof (+__real__ (Val)) == sizeof (+(Val))) \
? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0)) \
__tgml(Fct) (Val) \
: (__typeof__ (__real__ (__tgmath_real_type (Val)) 0)) \
@@ -312,8 +312,8 @@
/* XXX This definition has to be changed as soon as the compiler understands
the imaginary keyword. */
# define __TGMATH_BINARY_REAL_IMAG(Val1, Val2, Fct, Cfct) \
- (__extension__ (((sizeof (__real__ (Val1)) > sizeof (double) \
- || sizeof (__real__ (Val2)) > sizeof (double)) \
+ (__extension__ (((sizeof (+__real__ (Val1)) > sizeof (double) \
+ || sizeof (+__real__ (Val2)) > sizeof (double)) \
&& __builtin_classify_type (__real__ (Val1) \
+ __real__ (Val2)) == 8) \
? __TGMATH_CF128 ((Val1) + (Val2), \
@@ -326,28 +326,28 @@
+ (__tgmath_real_type (Val2)) 0)) \
Cfct, \
(Val1, Val2)) \
- ((sizeof (__real__ (Val1)) == sizeof (Val1) \
- && sizeof (__real__ (Val2)) == sizeof (Val2)) \
+ ((sizeof (+__real__ (Val1)) == sizeof (+(Val1)) \
+ && sizeof (+__real__ (Val2)) == sizeof (+(Val2))) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
__tgml(Fct) (Val1, Val2) \
: (__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
__tgml(Cfct) (Val1, Val2)) \
- : (sizeof (__real__ (Val1)) == sizeof (double) \
- || sizeof (__real__ (Val2)) == sizeof (double) \
+ : (sizeof (+__real__ (Val1)) == sizeof (double) \
+ || sizeof (+__real__ (Val2)) == sizeof (double) \
|| __builtin_classify_type (__real__ (Val1)) != 8 \
|| __builtin_classify_type (__real__ (Val2)) != 8) \
- ? ((sizeof (__real__ (Val1)) == sizeof (Val1) \
- && sizeof (__real__ (Val2)) == sizeof (Val2)) \
+ ? ((sizeof (+__real__ (Val1)) == sizeof (+(Val1)) \
+ && sizeof (+__real__ (Val2)) == sizeof (+(Val2))) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
Fct (Val1, Val2) \
: (__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
Cfct (Val1, Val2)) \
- : ((sizeof (__real__ (Val1)) == sizeof (Val1) \
- && sizeof (__real__ (Val2)) == sizeof (Val2)) \
+ : ((sizeof (+__real__ (Val1)) == sizeof (+(Val1)) \
+ && sizeof (+__real__ (Val2)) == sizeof (+(Val2))) \
? (__typeof ((__tgmath_real_type (Val1)) 0 \
+ (__tgmath_real_type (Val2)) 0)) \
Fct##f (Val1, Val2) \