-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[C99] Remove the tgmath.h header #135236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C99] Remove the tgmath.h header #135236
Conversation
Clang provides a number of headers which are required because the compiler is the only part of the implementation which can provide the correct macro definitions. Things like <limits.h> or <stdint.h> are such headers. <tgmath.h> is not something the compiler needs to provide macros for; it is the responsibility of the C Standard Library to provide these interfaces. Historically, Clang has provided tgmath.h from a time when C11 was still new and not all C Standard Libraries (such as the one from MSVC) had correct support. Today, that's no longer the case. So this change removes <tgmath.h> from the set of headers Clang provides and it is now on the user to provide a conforming C Standard Library if they would like to use this functionality.
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) ChangesClang provides a number of headers which are required because the compiler is the only part of the implementation which can provide the correct macro definitions. Things like <limits.h> or <stdint.h> are such headers. <tgmath.h> is not something the compiler needs to provide macros for; it is the responsibility of the C Standard Library to provide these interfaces. Historically, Clang has provided tgmath.h from a time when C11 was still new and not all C Standard Libraries (such as the one from MSVC) had correct support. Today, that's no longer the case. So this change removes <tgmath.h> from the set of headers Clang provides and it is now on the user to provide a conforming C Standard Library if they would like to use this functionality. Patch is 36.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135236.diff 10 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 77bf3355af9da..f7324ab130545 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -122,6 +122,9 @@ C Language Changes
- Clang now allows an ``inline`` specifier on a typedef declaration of a
function type in Microsoft compatibility mode. #GH124869
- Clang now allows ``restrict`` qualifier for array types with pointer elements (#GH92847).
+- Clang no longer provides the ``tgmath.h`` header as part of the compiler-
+ provided header files. This file needs to be provided by the C Standard
+ Library being compiled against.
C2y Feature Support
^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index acf49e40c447e..664c626590dc8 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -33,7 +33,6 @@ set(core_files
__stddef_wint_t.h
stdint.h
stdnoreturn.h
- tgmath.h
unwind.h
varargs.h
)
diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap
index dcaf09e8f2c55..3119aade1c957 100644
--- a/clang/lib/Headers/module.modulemap
+++ b/clang/lib/Headers/module.modulemap
@@ -305,11 +305,6 @@ module _Builtin_stdnoreturn [system] {
export *
}
-module _Builtin_tgmath [system] {
- header "tgmath.h"
- export *
-}
-
module _Builtin_unwind [system] {
header "unwind.h"
export *
diff --git a/clang/lib/Headers/tgmath.h b/clang/lib/Headers/tgmath.h
deleted file mode 100644
index 7acf18b9dd357..0000000000000
--- a/clang/lib/Headers/tgmath.h
+++ /dev/null
@@ -1,1368 +0,0 @@
-/*===---- tgmath.h - Standard header for type generic math ----------------===*\
- *
- * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- * See https://llvm.org/LICENSE.txt for license information.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- *
-\*===----------------------------------------------------------------------===*/
-
-#ifndef __CLANG_TGMATH_H
-#define __CLANG_TGMATH_H
-
-/* C99 7.22 Type-generic math <tgmath.h>. */
-#include <math.h>
-
-/*
- * Allow additional definitions and implementation-defined values on Apple
- * platforms. This is done after #include <math.h> to avoid depcycle conflicts
- * between libcxx and darwin in C++ modules builds.
- */
-#if defined(__APPLE__) && __STDC_HOSTED__ && __has_include_next(<tgmath.h>)
-# include_next <tgmath.h>
-#else
-
-/* C++ handles type genericity with overloading in math.h. */
-#ifndef __cplusplus
-#include <complex.h>
-
-#define _TG_ATTRSp __attribute__((__overloadable__))
-#define _TG_ATTRS __attribute__((__overloadable__, __always_inline__))
-
-// promotion
-
-typedef void _Argument_type_is_not_arithmetic;
-static _Argument_type_is_not_arithmetic __tg_promote(...)
- __attribute__((__unavailable__,__overloadable__));
-static double _TG_ATTRSp __tg_promote(int);
-static double _TG_ATTRSp __tg_promote(unsigned int);
-static double _TG_ATTRSp __tg_promote(long);
-static double _TG_ATTRSp __tg_promote(unsigned long);
-static double _TG_ATTRSp __tg_promote(long long);
-static double _TG_ATTRSp __tg_promote(unsigned long long);
-static float _TG_ATTRSp __tg_promote(float);
-static double _TG_ATTRSp __tg_promote(double);
-static long double _TG_ATTRSp __tg_promote(long double);
-static float _Complex _TG_ATTRSp __tg_promote(float _Complex);
-static double _Complex _TG_ATTRSp __tg_promote(double _Complex);
-static long double _Complex _TG_ATTRSp __tg_promote(long double _Complex);
-
-#define __tg_promote1(__x) (__typeof__(__tg_promote(__x)))
-#define __tg_promote2(__x, __y) (__typeof__(__tg_promote(__x) + \
- __tg_promote(__y)))
-#define __tg_promote3(__x, __y, __z) (__typeof__(__tg_promote(__x) + \
- __tg_promote(__y) + \
- __tg_promote(__z)))
-
-// acos
-
-static float
- _TG_ATTRS
- __tg_acos(float __x) {return acosf(__x);}
-
-static double
- _TG_ATTRS
- __tg_acos(double __x) {return acos(__x);}
-
-static long double
- _TG_ATTRS
- __tg_acos(long double __x) {return acosl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_acos(float _Complex __x) {return cacosf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_acos(double _Complex __x) {return cacos(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_acos(long double _Complex __x) {return cacosl(__x);}
-
-#undef acos
-#define acos(__x) __tg_acos(__tg_promote1((__x))(__x))
-
-// asin
-
-static float
- _TG_ATTRS
- __tg_asin(float __x) {return asinf(__x);}
-
-static double
- _TG_ATTRS
- __tg_asin(double __x) {return asin(__x);}
-
-static long double
- _TG_ATTRS
- __tg_asin(long double __x) {return asinl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_asin(float _Complex __x) {return casinf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_asin(double _Complex __x) {return casin(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_asin(long double _Complex __x) {return casinl(__x);}
-
-#undef asin
-#define asin(__x) __tg_asin(__tg_promote1((__x))(__x))
-
-// atan
-
-static float
- _TG_ATTRS
- __tg_atan(float __x) {return atanf(__x);}
-
-static double
- _TG_ATTRS
- __tg_atan(double __x) {return atan(__x);}
-
-static long double
- _TG_ATTRS
- __tg_atan(long double __x) {return atanl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_atan(float _Complex __x) {return catanf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_atan(double _Complex __x) {return catan(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_atan(long double _Complex __x) {return catanl(__x);}
-
-#undef atan
-#define atan(__x) __tg_atan(__tg_promote1((__x))(__x))
-
-// acosh
-
-static float
- _TG_ATTRS
- __tg_acosh(float __x) {return acoshf(__x);}
-
-static double
- _TG_ATTRS
- __tg_acosh(double __x) {return acosh(__x);}
-
-static long double
- _TG_ATTRS
- __tg_acosh(long double __x) {return acoshl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_acosh(float _Complex __x) {return cacoshf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_acosh(double _Complex __x) {return cacosh(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_acosh(long double _Complex __x) {return cacoshl(__x);}
-
-#undef acosh
-#define acosh(__x) __tg_acosh(__tg_promote1((__x))(__x))
-
-// asinh
-
-static float
- _TG_ATTRS
- __tg_asinh(float __x) {return asinhf(__x);}
-
-static double
- _TG_ATTRS
- __tg_asinh(double __x) {return asinh(__x);}
-
-static long double
- _TG_ATTRS
- __tg_asinh(long double __x) {return asinhl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_asinh(float _Complex __x) {return casinhf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_asinh(double _Complex __x) {return casinh(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_asinh(long double _Complex __x) {return casinhl(__x);}
-
-#undef asinh
-#define asinh(__x) __tg_asinh(__tg_promote1((__x))(__x))
-
-// atanh
-
-static float
- _TG_ATTRS
- __tg_atanh(float __x) {return atanhf(__x);}
-
-static double
- _TG_ATTRS
- __tg_atanh(double __x) {return atanh(__x);}
-
-static long double
- _TG_ATTRS
- __tg_atanh(long double __x) {return atanhl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_atanh(float _Complex __x) {return catanhf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_atanh(double _Complex __x) {return catanh(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_atanh(long double _Complex __x) {return catanhl(__x);}
-
-#undef atanh
-#define atanh(__x) __tg_atanh(__tg_promote1((__x))(__x))
-
-// cos
-
-static float
- _TG_ATTRS
- __tg_cos(float __x) {return cosf(__x);}
-
-static double
- _TG_ATTRS
- __tg_cos(double __x) {return cos(__x);}
-
-static long double
- _TG_ATTRS
- __tg_cos(long double __x) {return cosl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_cos(float _Complex __x) {return ccosf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_cos(double _Complex __x) {return ccos(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_cos(long double _Complex __x) {return ccosl(__x);}
-
-#undef cos
-#define cos(__x) __tg_cos(__tg_promote1((__x))(__x))
-
-// sin
-
-static float
- _TG_ATTRS
- __tg_sin(float __x) {return sinf(__x);}
-
-static double
- _TG_ATTRS
- __tg_sin(double __x) {return sin(__x);}
-
-static long double
- _TG_ATTRS
- __tg_sin(long double __x) {return sinl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_sin(float _Complex __x) {return csinf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_sin(double _Complex __x) {return csin(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_sin(long double _Complex __x) {return csinl(__x);}
-
-#undef sin
-#define sin(__x) __tg_sin(__tg_promote1((__x))(__x))
-
-// tan
-
-static float
- _TG_ATTRS
- __tg_tan(float __x) {return tanf(__x);}
-
-static double
- _TG_ATTRS
- __tg_tan(double __x) {return tan(__x);}
-
-static long double
- _TG_ATTRS
- __tg_tan(long double __x) {return tanl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_tan(float _Complex __x) {return ctanf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_tan(double _Complex __x) {return ctan(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_tan(long double _Complex __x) {return ctanl(__x);}
-
-#undef tan
-#define tan(__x) __tg_tan(__tg_promote1((__x))(__x))
-
-// cosh
-
-static float
- _TG_ATTRS
- __tg_cosh(float __x) {return coshf(__x);}
-
-static double
- _TG_ATTRS
- __tg_cosh(double __x) {return cosh(__x);}
-
-static long double
- _TG_ATTRS
- __tg_cosh(long double __x) {return coshl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_cosh(float _Complex __x) {return ccoshf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_cosh(double _Complex __x) {return ccosh(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_cosh(long double _Complex __x) {return ccoshl(__x);}
-
-#undef cosh
-#define cosh(__x) __tg_cosh(__tg_promote1((__x))(__x))
-
-// sinh
-
-static float
- _TG_ATTRS
- __tg_sinh(float __x) {return sinhf(__x);}
-
-static double
- _TG_ATTRS
- __tg_sinh(double __x) {return sinh(__x);}
-
-static long double
- _TG_ATTRS
- __tg_sinh(long double __x) {return sinhl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_sinh(float _Complex __x) {return csinhf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_sinh(double _Complex __x) {return csinh(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_sinh(long double _Complex __x) {return csinhl(__x);}
-
-#undef sinh
-#define sinh(__x) __tg_sinh(__tg_promote1((__x))(__x))
-
-// tanh
-
-static float
- _TG_ATTRS
- __tg_tanh(float __x) {return tanhf(__x);}
-
-static double
- _TG_ATTRS
- __tg_tanh(double __x) {return tanh(__x);}
-
-static long double
- _TG_ATTRS
- __tg_tanh(long double __x) {return tanhl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_tanh(float _Complex __x) {return ctanhf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_tanh(double _Complex __x) {return ctanh(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_tanh(long double _Complex __x) {return ctanhl(__x);}
-
-#undef tanh
-#define tanh(__x) __tg_tanh(__tg_promote1((__x))(__x))
-
-// exp
-
-static float
- _TG_ATTRS
- __tg_exp(float __x) {return expf(__x);}
-
-static double
- _TG_ATTRS
- __tg_exp(double __x) {return exp(__x);}
-
-static long double
- _TG_ATTRS
- __tg_exp(long double __x) {return expl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_exp(float _Complex __x) {return cexpf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_exp(double _Complex __x) {return cexp(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_exp(long double _Complex __x) {return cexpl(__x);}
-
-#undef exp
-#define exp(__x) __tg_exp(__tg_promote1((__x))(__x))
-
-// log
-
-static float
- _TG_ATTRS
- __tg_log(float __x) {return logf(__x);}
-
-static double
- _TG_ATTRS
- __tg_log(double __x) {return log(__x);}
-
-static long double
- _TG_ATTRS
- __tg_log(long double __x) {return logl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_log(float _Complex __x) {return clogf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_log(double _Complex __x) {return clog(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_log(long double _Complex __x) {return clogl(__x);}
-
-#undef log
-#define log(__x) __tg_log(__tg_promote1((__x))(__x))
-
-// pow
-
-static float
- _TG_ATTRS
- __tg_pow(float __x, float __y) {return powf(__x, __y);}
-
-static double
- _TG_ATTRS
- __tg_pow(double __x, double __y) {return pow(__x, __y);}
-
-static long double
- _TG_ATTRS
- __tg_pow(long double __x, long double __y) {return powl(__x, __y);}
-
-static float _Complex
- _TG_ATTRS
- __tg_pow(float _Complex __x, float _Complex __y) {return cpowf(__x, __y);}
-
-static double _Complex
- _TG_ATTRS
- __tg_pow(double _Complex __x, double _Complex __y) {return cpow(__x, __y);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_pow(long double _Complex __x, long double _Complex __y)
- {return cpowl(__x, __y);}
-
-#undef pow
-#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \
- __tg_promote2((__x), (__y))(__y))
-
-// sqrt
-
-static float
- _TG_ATTRS
- __tg_sqrt(float __x) {return sqrtf(__x);}
-
-static double
- _TG_ATTRS
- __tg_sqrt(double __x) {return sqrt(__x);}
-
-static long double
- _TG_ATTRS
- __tg_sqrt(long double __x) {return sqrtl(__x);}
-
-static float _Complex
- _TG_ATTRS
- __tg_sqrt(float _Complex __x) {return csqrtf(__x);}
-
-static double _Complex
- _TG_ATTRS
- __tg_sqrt(double _Complex __x) {return csqrt(__x);}
-
-static long double _Complex
- _TG_ATTRS
- __tg_sqrt(long double _Complex __x) {return csqrtl(__x);}
-
-#undef sqrt
-#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x))
-
-// fabs
-
-static float
- _TG_ATTRS
- __tg_fabs(float __x) {return fabsf(__x);}
-
-static double
- _TG_ATTRS
- __tg_fabs(double __x) {return fabs(__x);}
-
-static long double
- _TG_ATTRS
- __tg_fabs(long double __x) {return fabsl(__x);}
-
-static float
- _TG_ATTRS
- __tg_fabs(float _Complex __x) {return cabsf(__x);}
-
-static double
- _TG_ATTRS
- __tg_fabs(double _Complex __x) {return cabs(__x);}
-
-static long double
- _TG_ATTRS
- __tg_fabs(long double _Complex __x) {return cabsl(__x);}
-
-#undef fabs
-#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x))
-
-// atan2
-
-static float
- _TG_ATTRS
- __tg_atan2(float __x, float __y) {return atan2f(__x, __y);}
-
-static double
- _TG_ATTRS
- __tg_atan2(double __x, double __y) {return atan2(__x, __y);}
-
-static long double
- _TG_ATTRS
- __tg_atan2(long double __x, long double __y) {return atan2l(__x, __y);}
-
-#undef atan2
-#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \
- __tg_promote2((__x), (__y))(__y))
-
-// cbrt
-
-static float
- _TG_ATTRS
- __tg_cbrt(float __x) {return cbrtf(__x);}
-
-static double
- _TG_ATTRS
- __tg_cbrt(double __x) {return cbrt(__x);}
-
-static long double
- _TG_ATTRS
- __tg_cbrt(long double __x) {return cbrtl(__x);}
-
-#undef cbrt
-#define cbrt(__x) __tg_cbrt(__tg_promote1((__x))(__x))
-
-// ceil
-
-static float
- _TG_ATTRS
- __tg_ceil(float __x) {return ceilf(__x);}
-
-static double
- _TG_ATTRS
- __tg_ceil(double __x) {return ceil(__x);}
-
-static long double
- _TG_ATTRS
- __tg_ceil(long double __x) {return ceill(__x);}
-
-#undef ceil
-#define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x))
-
-// copysign
-
-static float
- _TG_ATTRS
- __tg_copysign(float __x, float __y) {return copysignf(__x, __y);}
-
-static double
- _TG_ATTRS
- __tg_copysign(double __x, double __y) {return copysign(__x, __y);}
-
-static long double
- _TG_ATTRS
- __tg_copysign(long double __x, long double __y) {return copysignl(__x, __y);}
-
-#undef copysign
-#define copysign(__x, __y) __tg_copysign(__tg_promote2((__x), (__y))(__x), \
- __tg_promote2((__x), (__y))(__y))
-
-// erf
-
-static float
- _TG_ATTRS
- __tg_erf(float __x) {return erff(__x);}
-
-static double
- _TG_ATTRS
- __tg_erf(double __x) {return erf(__x);}
-
-static long double
- _TG_ATTRS
- __tg_erf(long double __x) {return erfl(__x);}
-
-#undef erf
-#define erf(__x) __tg_erf(__tg_promote1((__x))(__x))
-
-// erfc
-
-static float
- _TG_ATTRS
- __tg_erfc(float __x) {return erfcf(__x);}
-
-static double
- _TG_ATTRS
- __tg_erfc(double __x) {return erfc(__x);}
-
-static long double
- _TG_ATTRS
- __tg_erfc(long double __x) {return erfcl(__x);}
-
-#undef erfc
-#define erfc(__x) __tg_erfc(__tg_promote1((__x))(__x))
-
-// exp2
-
-static float
- _TG_ATTRS
- __tg_exp2(float __x) {return exp2f(__x);}
-
-static double
- _TG_ATTRS
- __tg_exp2(double __x) {return exp2(__x);}
-
-static long double
- _TG_ATTRS
- __tg_exp2(long double __x) {return exp2l(__x);}
-
-#undef exp2
-#define exp2(__x) __tg_exp2(__tg_promote1((__x))(__x))
-
-// expm1
-
-static float
- _TG_ATTRS
- __tg_expm1(float __x) {return expm1f(__x);}
-
-static double
- _TG_ATTRS
- __tg_expm1(double __x) {return expm1(__x);}
-
-static long double
- _TG_ATTRS
- __tg_expm1(long double __x) {return expm1l(__x);}
-
-#undef expm1
-#define expm1(__x) __tg_expm1(__tg_promote1((__x))(__x))
-
-// fdim
-
-static float
- _TG_ATTRS
- __tg_fdim(float __x, float __y) {return fdimf(__x, __y);}
-
-static double
- _TG_ATTRS
- __tg_fdim(double __x, double __y) {return fdim(__x, __y);}
-
-static long double
- _TG_ATTRS
- __tg_fdim(long double __x, long double __y) {return fdiml(__x, __y);}
-
-#undef fdim
-#define fdim(__x, __y) __tg_fdim(__tg_promote2((__x), (__y))(__x), \
- __tg_promote2((__x), (__y))(__y))
-
-// floor
-
-static float
- _TG_ATTRS
- __tg_floor(float __x) {return floorf(__x);}
-
-static double
- _TG_ATTRS
- __tg_floor(double __x) {return floor(__x);}
-
-static long double
- _TG_ATTRS
- __tg_floor(long double __x) {return floorl(__x);}
-
-#undef floor
-#define floor(__x) __tg_floor(__tg_promote1((__x))(__x))
-
-// fma
-
-static float
- _TG_ATTRS
- __tg_fma(float __x, float __y, float __z)
- {return fmaf(__x, __y, __z);}
-
-static double
- _TG_ATTRS
- __tg_fma(double __x, double __y, double __z)
- {return fma(__x, __y, __z);}
-
-static long double
- _TG_ATTRS
- __tg_fma(long double __x,long double __y, long double __z)
- {return fmal(__x, __y, __z);}
-
-#undef fma
-#define fma(__x, __y, __z) \
- __tg_fma(__tg_promote3((__x), (__y), (__z))(__x), \
- __tg_promote3((__x), (__y), (__z))(__y), \
- __tg_promote3((__x), (__y), (__z))(__z))
-
-// fmax
-
-static float
- _TG_ATTRS
- __tg_fmax(float __x, float __y) {return fmaxf(__x, __y);}
-
-static double
- _TG_ATTRS
- __tg_fmax(double __x, double __y) {return fmax(__x, __y);}
-
-static long double
- _TG_ATTRS
- __tg_fmax(long double __x, long double __y) {return fmaxl(__x, __y);}
-
-#undef fmax
-#define fmax(__x, __y) __tg_fmax(__tg_promote2((__x), (__y))(__x), \
- __tg_promote2((__x), (__y))(__y))
-
-// fmin
-
-static float
- _TG_ATTRS
- __tg_fmin(float __x, float __y) {return fminf(__x, __y);}
-
-static double
- _TG_ATTRS
- __tg_fmin(double __x, double __y) {return fmin(__x, __y);}
-
-static long double
- _TG_ATTRS
- __tg_fmin(long double __x, long double __y) {return fminl(__x, __y);}
-
-#undef fmin
-#define fmin(__x, __y) __tg_fmin(__tg_promote2((__x), (__y))(__x), \
- __tg_promote2((__x), (__y))(__y))
-
-// fmod
-
-static float
- _TG_ATTRS
- __tg_fmod(float __x, float __y) {return fmodf(__x, __y);}
-
-static double
- _TG_ATTRS
- ...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp -- clang/lib/Lex/ModuleMap.cpp View the diff from clang-format here.diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index f16fe414e..1c2fcaf07 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -253,17 +253,17 @@ OptionalFileEntryRef ModuleMap::findHeader(
/// headers.
static bool isBuiltinHeaderName(StringRef FileName) {
return llvm::StringSwitch<bool>(FileName)
- .Case("float.h", true)
- .Case("iso646.h", true)
- .Case("limits.h", true)
- .Case("stdalign.h", true)
- .Case("stdarg.h", true)
- .Case("stdatomic.h", true)
- .Case("stdbool.h", true)
- .Case("stddef.h", true)
- .Case("stdint.h", true)
- .Case("unwind.h", true)
- .Default(false);
+ .Case("float.h", true)
+ .Case("iso646.h", true)
+ .Case("limits.h", true)
+ .Case("stdalign.h", true)
+ .Case("stdarg.h", true)
+ .Case("stdatomic.h", true)
+ .Case("stdbool.h", true)
+ .Case("stddef.h", true)
+ .Case("stdint.h", true)
+ .Case("unwind.h", true)
+ .Default(false);
}
/// Determine whether the given module name is the name of a builtin
|
Background: it's not clear to me which C Standard Library headers Clang should or should not provide, so perhaps this change is wrong for reasons I don't understand. However, we have a number of open bug reports about our implementation of tgmath.h, and there are further changes needed for C23 (like adding |
IBM's AIX ships a |
Thank you for pointing that out! So IBM still needs Clang to vend this for now, I take it? Is IBM planning to update their tgmath.h so that it works with the Clang-based XL compiler (so we can eventually remove Clang's)? |
Historically, the easiest line to draw has been that we aim to provide the freestanding headers. This matches GCC's documented position that it provides a complete conforming freestanding implementation, or the compiler for a hosted implementation. For some reason, WG21 has trampled over that meaning of "freestanding" and we no longer have such a separation for C++, but it still exists for C, so it makes sense to still follow it there. And There are sometimes other reasons why we might feel like we should be providing a header rather than leaving it to the C standard library implementation, and in particular I wonder if we can put it into an AIX-only (plus whatever other targets still need it) include directory, though, so we only find and use it on the targets where it's necessary? |
The road to being able to retain the functionality with Clang while also removing the header from Clang is a long one. Enabling use of the system |
That, or, generally |
Possibly. But if so, we should use a pattern like #if we want our tgmath
#include <__clang_tgmath.h>
#else
#include_next <tgmath.h>
#endif so we're not unnecessarily tokenizing the whole file, and so we can just put the |
Does it make sense to keep the tests for all platforms then? If we decide to restrict the testing to the platforms expected to use the Clang-provided header, then I think it should at least be staged so that there is some CI cycle where the tests are run regardless (in case the system header is problematic for use with Clang on more platforms). |
Same for z/OS. |
See #132232. |
My attempt at doing, with Clang, what the glibc implementation of #include <math.h>
#include <complex.h>
int main(void) {
return _Generic(__builtin_tgmath(
sinf, sin, sinl, csinf, csin, csinl,
0.L), default: 0);
}
|
I see. The glibc header comment gives an idea of what's going on here: /* There are two variant implementations of type-generic macros in
this file: one for GCC 8 and later, using __builtin_tgmath and
where each macro expands each of its arguments only once, and one
for older GCC, using other compiler extensions but with macros
expanding their arguments many times (so resulting in exponential
blowup of the size of expansions when calls to such macros are
nested inside arguments to such macros). */ Indeed, it seems that So it looks like the world is unprepared for us to not provide our own |
A few datapoints:
But notably... those all suck. Every one of them macro expands the arguments repeatedly (leading to exponential code size for deeply nested calls) and expands to a pretty huge macro invocation. The current Clang implementation is better than all of these. Maybe that's sufficient reason to keep it. |
Clang would either need to change its |
Sigh. So we can't use "freestanding" as the line between compiler and standard library anywhere any more, not even in C. |
What I am taking away from this conversation is: 1) We need to keep tgmath.h, so this PR can be closed. 2) We should consider implementing Thank you all for the good discussion on this! |
Clang provides a number of headers which are required because the compiler is the only part of the implementation which can provide the correct macro definitions. Things like <limits.h> or <stdint.h> are such headers.
<tgmath.h> is not something the compiler needs to provide macros for; it is the responsibility of the C Standard Library to provide these interfaces.
Historically, Clang has provided tgmath.h from a time when C11 was still new and not all C Standard Libraries (such as the one from MSVC) had correct support. Today, that's no longer the case. So this change removes <tgmath.h> from the set of headers Clang provides and it is now on the user to provide a conforming C Standard Library if they would like to use this functionality.