From: Joseph Myers Date: Wed, 2 Aug 2017 16:09:01 +0000 (+0000) Subject: Fix tgmath.h for bit-fields (bug 21685). X-Git-Tag: glibc-2.27~1254 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=2fee621de0776a6e729c3b18c27442e00733f2b2;p=glibc.git 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. --- diff --git a/ChangeLog b/ChangeLog index 337d37e87f..75cc492923 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2017-08-02 Joseph Myers + + [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. + 2017-08-02 H.J. Lu [BZ #21791] 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) \