re PR c++/5998 (regression, all builtins disabled)

* include/c_std/std_cmath.h:  To prevent problems overloading
	g++ builtins, use the double variants from the global namespace
	before defining float and long double variants in std::.

	PR c++/5998:
	* decl.c (cxx_init_decl_processing): Re-enable built-in functions
	in the g++ front-end.
	(duplicate_decl): Allow redefinition of anticipated built-ins.
	Fix inlining problem by over-writing the old DECL_RTL.
	(lookup_namespace_name): Fail to find an identifier in the
	specified namespace if its still anticipated.
	(builtin_function_1): New function split out from builtin_function
	to create a builtin in the current namespace with given context.
	(builtin_function): Call builtin_function_1 to define the
	appropriate builtins in both the std and global namespaces.
	(select_decl): Don't test for anticipated decls here.
	(unqualified_namespace_lookup): Instead ignore them whilst
	searching through scopes and namespaces.
	* decl2.c (do_nonmember_using_decl): If a using declaration
	specifies an anticipated built-in function, mark it as no longer
	anticipated in that scope.
	(ambiguous_decl):  Avoid resolving to an anticipated decl.
	* lex.c (do_scoped_id): Fail to find an identifier in the global
	namespace if its still anticipated.

	* g++.old-deja/g++.other/builtins5.C: New test.
	* g++.old-deja/g++.other/builtins6.C: New test.
	* g++.old-deja/g++.other/builtins7.C: New test.
	* g++.old-deja/g++.other/builtins8.C: New test.
	* g++.old-deja/g++.other/builtins9.C: New test.

From-SVN: r51568
This commit is contained in:
Roger Sayle 2002-03-29 20:41:53 +00:00 committed by Mark Mitchell
parent 5843e8704e
commit d52e4867ca
12 changed files with 267 additions and 88 deletions

View File

@ -1,3 +1,26 @@
2002-03-28 Roger Sayle <roger@eyesopen.com>
PR c++/5998:
* decl.c (cxx_init_decl_processing): Re-enable built-in functions
in the g++ front-end.
(duplicate_decl): Allow redefinition of anticipated built-ins.
Fix inlining problem by over-writing the old DECL_RTL.
(lookup_namespace_name): Fail to find an identifier in the
specified namespace if its still anticipated.
(builtin_function_1): New function split out from builtin_function
to create a builtin in the current namespace with given context.
(builtin_function): Call builtin_function_1 to define the
appropriate builtins in both the std and global namespaces.
(select_decl): Don't test for anticipated decls here.
(unqualified_namespace_lookup): Instead ignore them whilst
searching through scopes and namespaces.
* decl2.c (do_nonmember_using_decl): If a using declaration
specifies an anticipated built-in function, mark it as no longer
anticipated in that scope.
(ambiguous_decl): Avoid resolving to an anticipated decl.
* lex.c (do_scoped_id): Fail to find an identifier in the global
namespace if its still anticipated.
2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_MAKE_TYPE): Redefine.

View File

@ -87,6 +87,8 @@ static tree lookup_tag PARAMS ((enum tree_code, tree,
static void set_identifier_type_value_with_scope
PARAMS ((tree, tree, struct binding_level *));
static void record_unknown_type PARAMS ((tree, const char *));
static tree builtin_function_1 PARAMS ((const char *, tree, tree, int,
enum built_in_class, const char *));
static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
@ -3145,6 +3147,10 @@ duplicate_decls (newdecl, olddecl)
{
if (TREE_CODE (newdecl) != FUNCTION_DECL)
{
/* Avoid warnings redeclaring anticipated built-ins. */
if (DECL_ANTICIPATED (olddecl))
return 0;
/* If you declare a built-in or predefined function name as static,
the old definition is overridden, but optionally warn this was a
bad choice of name. */
@ -3172,7 +3178,10 @@ duplicate_decls (newdecl, olddecl)
}
else if (!types_match)
{
if ((DECL_EXTERN_C_P (newdecl)
/* Avoid warnings redeclaring anticipated built-ins. */
if (DECL_ANTICIPATED (olddecl))
; /* Do nothing yet. */
else if ((DECL_EXTERN_C_P (newdecl)
&& DECL_EXTERN_C_P (olddecl))
|| compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
@ -3614,6 +3623,7 @@ duplicate_decls (newdecl, olddecl)
TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
COPY_DECL_RTL (newdecl, olddecl);
}
/* Merge the storage class information. */
@ -5507,7 +5517,12 @@ lookup_namespace_name (namespace, name)
/* If we have a single function from a using decl, pull it out. */
if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
val = OVL_FUNCTION (val);
return val;
/* Ignore built-in functions that haven't been prototyped yet. */
if (!val || !DECL_P(val)
|| !DECL_LANG_SPECIFIC(val)
|| !DECL_ANTICIPATED (val))
return val;
}
error ("`%D' undeclared in namespace `%D'", name, namespace);
@ -5786,14 +5801,6 @@ select_decl (binding, flags)
tree val;
val = BINDING_VALUE (binding);
/* When we implicitly declare some builtin entity, we mark it
DECL_ANTICIPATED, so that we know to ignore it until it is
really declared. */
if (val && DECL_P (val)
&& DECL_LANG_SPECIFIC (val)
&& DECL_ANTICIPATED (val))
return NULL_TREE;
if (LOOKUP_NAMESPACES_ONLY (flags))
{
/* We are not interested in types. */
@ -5843,9 +5850,21 @@ unqualified_namespace_lookup (name, flags, spacesp)
*spacesp = tree_cons (scope, NULL_TREE, *spacesp);
val = binding_for_name (name, scope);
/* Initialize binding for this context. */
BINDING_VALUE (b) = BINDING_VALUE (val);
BINDING_TYPE (b) = BINDING_TYPE (val);
/* Ignore anticipated built-in functions. */
if (val && BINDING_VALUE (val)
&& DECL_P (BINDING_VALUE (val))
&& DECL_LANG_SPECIFIC (BINDING_VALUE (val))
&& DECL_ANTICIPATED (BINDING_VALUE (val)))
{
BINDING_VALUE (b) = NULL_TREE;
BINDING_TYPE (b) = NULL_TREE;
}
else
{
/* Initialize binding for this context. */
BINDING_VALUE (b) = BINDING_VALUE (val);
BINDING_TYPE (b) = BINDING_TYPE (val);
}
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
@ -6435,12 +6454,6 @@ cxx_init_decl_processing ()
flag_inline_functions = 0;
}
/* In C++, we never create builtin functions whose name does not
begin with `__'. Users should be using headers to get prototypes
in C++. It would be nice if we could warn when `-fbuiltin' is
used explicitly, but we do not have that information. */
flag_no_builtin = 1;
/* Initially, C. */
current_lang_name = lang_name_c;
@ -6704,10 +6717,9 @@ cp_make_fname_decl (id, type_dep)
return decl;
}
/* Entry point for the benefit of c_common_nodes_and_builtins.
Make a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types.
/* Make a definition for a builtin function named NAME in the current
namespace, whose data type is TYPE and whose context is CONTEXT.
TYPE should be a function type with argument types.
CLASS and CODE tell later passes how to compile calls to this function.
See tree.h for possible values.
@ -6715,10 +6727,11 @@ cp_make_fname_decl (id, type_dep)
If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
the name to be called if we can't opencode the function. */
tree
builtin_function (name, type, code, class, libname)
static tree
builtin_function_1 (name, type, context, code, class, libname)
const char *name;
tree type;
tree context;
int code;
enum built_in_class class;
const char *libname;
@ -6726,23 +6739,13 @@ builtin_function (name, type, code, class, libname)
tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = code;
DECL_CONTEXT (decl) = context;
/* The return builtins leave the current function. */
if (code == BUILT_IN_RETURN || code == BUILT_IN_EH_RETURN)
TREE_THIS_VOLATILE (decl) = 1;
my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
/* All builtins that don't begin with an `_' should go in the `std'
namespace. */
if (name[0] != '_')
{
push_namespace (std_identifier);
DECL_CONTEXT (decl) = std_node;
}
pushdecl (decl);
if (name[0] != '_')
pop_namespace ();
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
we cannot change DECL_ASSEMBLER_NAME until we have installed this
@ -6762,6 +6765,39 @@ builtin_function (name, type, code, class, libname)
return decl;
}
/* Entry point for the benefit of c_common_nodes_and_builtins.
Make a defintion for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types. This
function places the anticipated declaration in the global namespace
and additionally in the std namespace if appropriate.
CLASS and CODE tell later passes how to compile calls to this function.
See tree.h for possible values.
If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
the name to be called if we can't opencode the function. */
tree
builtin_function (name, type, code, class, libname)
const char *name;
tree type;
int code;
enum built_in_class class;
const char *libname;
{
/* All builtins that don't begin with an '_' should additionally
go in the 'std' namespace. */
if (name[0] != '_')
{
push_namespace (std_identifier);
builtin_function_1 (name, type, std_node, code, class, libname);
pop_namespace ();
}
return builtin_function_1 (name, type, NULL_TREE, code, class, libname);
}
/* Generate a FUNCTION_DECL with the typical flags for a runtime library
function. Not called directly. */

View File

@ -4178,6 +4178,11 @@ ambiguous_decl (name, old, new, flags)
if (LOOKUP_TYPES_ONLY (flags))
val = NULL_TREE;
break;
case FUNCTION_DECL:
/* Ignore built-in functions that are still anticipated. */
if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
val = NULL_TREE;
break;
default:
if (LOOKUP_QUALIFIERS_ONLY (flags))
val = NULL_TREE;
@ -4930,6 +4935,15 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
{
/* If this using declaration introduces a function
recognized as a built-in, no longer mark it as
anticipated in this scope. */
if (DECL_ANTICIPATED (old_fn))
{
DECL_ANTICIPATED (old_fn) = 0;
break;
}
/* There was already a non-using declaration in
this scope with the same parameter types. If both
are the same extern "C" functions, that's ok. */

View File

@ -1326,7 +1326,8 @@ do_scoped_id (token, parsing)
id = IDENTIFIER_GLOBAL_VALUE (token);
if (parsing && yychar == YYEMPTY)
yychar = yylex ();
if (! id)
if (!id || (TREE_CODE (id) == FUNCTION_DECL
&& DECL_ANTICIPATED (id)))
{
if (processing_template_decl)
{

View File

@ -1,3 +1,11 @@
2002-03-28 Roger Sayle <roger@eyesopen.com>
* g++.old-deja/g++.other/builtins5.C: New test.
* g++.old-deja/g++.other/builtins6.C: New test.
* g++.old-deja/g++.other/builtins7.C: New test.
* g++.old-deja/g++.other/builtins8.C: New test.
* g++.old-deja/g++.other/builtins9.C: New test.
2002-03-29 Jakub Jelinek <jakub@redhat.com>
* g++.dg/opt/static1.C: New test.

View File

@ -0,0 +1,16 @@
// Build don't link:
// Test that built-in functions aren't recognized without a prototype.
// Origin: Roger Sayle Mar 20, 2002
// Copyright (C) 2002 Free Software Foundation.
int
foo ()
{
return (int) ::strlen ("foo"); // ERROR - undeclared
}
int
bar ()
{
return (int) std::strlen ("bar"); // ERROR - undeclared
}

View File

@ -0,0 +1,18 @@
// Test that built-in functions are recognized with a prototype.
// Origin: Roger Sayle Mar 20, 2002
// Copyright (C) 2002 Free Software Foundation.
//
// Special g++ Options: -O2
typedef __SIZE_TYPE__ size_t;
extern "C" size_t strlen (const char*);
extern "C" void link_error (void);
int
main ()
{
if (strlen ("foo") != 3)
link_error ();
return 0;
}

View File

@ -0,0 +1,20 @@
// Test that built-in functions are recognized with a prototype.
// Origin: Roger Sayle Mar 20, 2002
// Copyright (C) 2002 Free Software Foundation.
//
// Special g++ Options: -O2
extern "C" void link_error (void);
namespace std {
typedef __SIZE_TYPE__ size_t;
extern "C" size_t strlen (const char*);
}
int
main ()
{
if (std::strlen ("foo") != 3)
link_error ();
return 0;
}

View File

@ -0,0 +1,24 @@
// Test that built-in functions are recognized with a prototype.
// Origin: Roger Sayle Mar 20, 2002
// Copyright (C) 2002 Free Software Foundation.
//
// Special g++ Options: -O2
extern "C" void link_error (void);
namespace std {
typedef __SIZE_TYPE__ size_t;
extern "C" size_t strlen (const char*);
}
using namespace std;
int
main ()
{
if (strlen ("foo") != 3)
link_error ();
return 0;
}

View File

@ -0,0 +1,13 @@
// Test that inline redeclarations of builtins are emitted.
// Origin: Roger Sayle Mar 28, 2002
// Copyright (C) 2002 Free Software Foundation.
namespace std {
inline int fabs (void) { return 0; }
}
int main ()
{
return std::fabs ();
}

View File

@ -1,3 +1,9 @@
2002-03-27 Roger Sayle <roger@eyesopen.com>
* include/c_std/std_cmath.h: To prevent problems overloading
g++ builtins, use the double variants from the global namespace
before defining float and long double variants in std::.
2002-03-28 Loren J. Rittle <ljrittle@acm.org>
* testsuite/18_support/numeric_limits.cc (test_extrema): Fix typo.

View File

@ -89,14 +89,14 @@ namespace std
return __x < _Tp() ? -__x : __x;
}
inline float
abs(float __x)
{ return __builtin_fabsf(__x); }
inline double
abs(double __x)
{ return __builtin_fabs(__x); }
inline float
abs(float __x)
{ return __builtin_fabsf(__x); }
inline long double
abs(long double __x)
{ return __builtin_fabsl(__x); }
@ -119,6 +119,8 @@ namespace std
acos(long double __x) { return ::acos(static_cast<double>(__x)); }
#endif
using ::asin;
#if _GLIBCPP_HAVE_ASINF
inline float
asin(float __x) { return ::asinf(__x); }
@ -127,8 +129,6 @@ namespace std
asin(float __x) { return ::asin(static_cast<double>(__x)); }
#endif
using ::asin;
#if _GLIBCPP_HAVE_ASINL
inline long double
asin(long double __x) { return ::asinl(__x); }
@ -137,6 +137,8 @@ namespace std
asin(long double __x) { return ::asin(static_cast<double>(__x)); }
#endif
using ::atan;
#if _GLIBCPP_HAVE_ATANF
inline float
atan(float __x) { return ::atanf(__x); }
@ -145,8 +147,6 @@ namespace std
atan(float __x) { return ::atan(static_cast<double>(__x)); }
#endif
using ::atan;
#if _GLIBCPP_HAVE_ATANL
inline long double
atan(long double __x) { return ::atanl(__x); }
@ -155,6 +155,8 @@ namespace std
atan(long double __x) { return ::atan(static_cast<double>(__x)); }
#endif
using ::atan2;
#if _GLIBCPP_HAVE_ATAN2F
inline float
atan2(float __y, float __x) { return ::atan2f(__y, __x); }
@ -164,8 +166,6 @@ namespace std
{ return ::atan2(static_cast<double>(__y), static_cast<double>(__x)); }
#endif
using ::atan2;
#if _GLIBCPP_HAVE_ATAN2L
inline long double
atan2(long double __y, long double __x) { return ::atan2l(__y, __x); }
@ -175,6 +175,8 @@ namespace std
{ return ::atan2(static_cast<double>(__y), static_cast<double>(__x)); }
#endif
using ::ceil;
#if _GLIBCPP_HAVE_CEILF
inline float
ceil(float __x) { return ::ceilf(__x); }
@ -183,8 +185,6 @@ namespace std
ceil(float __x) { return ::ceil(static_cast<double>(__x)); }
#endif
using ::ceil;
#if _GLIBCPP_HAVE_CEILL
inline long double
ceil(long double __x) { return ::ceill(__x); }
@ -193,16 +193,18 @@ namespace std
ceil(long double __x) { return ::ceil(static_cast<double>(__x)); }
#endif
using ::cos;
inline float
cos(float __x)
{ return __builtin_cosf(__x); }
using ::cos;
inline long double
cos(long double __x)
{ return __builtin_cosl(__x); }
using ::cosh;
#if _GLIBCPP_HAVE_COSHF
inline float
cosh(float __x) { return ::coshf(__x); }
@ -211,8 +213,6 @@ namespace std
cosh(float __x) { return ::cosh(static_cast<double>(__x)); }
#endif
using ::cosh;
#if _GLIBCPP_HAVE_COSHL
inline long double
cosh(long double __x) { return ::coshl(__x); }
@ -221,6 +221,8 @@ namespace std
cosh(long double __x) { return ::cosh(static_cast<double>(__x)); }
#endif
using ::exp;
#if _GLIBCPP_HAVE_EXPF
inline float
exp(float __x) { return ::expf(__x); }
@ -229,8 +231,6 @@ namespace std
exp(float __x) { return ::exp(static_cast<double>(__x)); }
#endif
using ::exp;
#if _GLIBCPP_HAVE_EXPL
inline long double
exp(long double __x) { return ::expl(__x); }
@ -239,16 +239,18 @@ namespace std
exp(long double __x) { return ::exp(static_cast<double>(__x)); }
#endif
using ::fabs;
inline float
fabs(float __x)
{ return __builtin_fabsf(__x); }
using ::fabs;
inline long double
fabs(long double __x)
{ return __builtin_fabsl(__x); }
using ::floor;
#if _GLIBCPP_HAVE_FLOORF
inline float
floor(float __x) { return ::floorf(__x); }
@ -257,8 +259,6 @@ namespace std
floor(float __x) { return ::floor(static_cast<double>(__x)); }
#endif
using ::floor;
#if _GLIBCPP_HAVE_FLOORL
inline long double
floor(long double __x) { return ::floorl(__x); }
@ -267,6 +267,8 @@ namespace std
floor(long double __x) { return ::floor(static_cast<double>(__x)); }
#endif
using ::fmod;
#if _GLIBCPP_HAVE_FMODF
inline float
fmod(float __x, float __y) { return ::fmodf(__x, __y); }
@ -276,8 +278,6 @@ namespace std
{ return ::fmod(static_cast<double>(__x), static_cast<double>(__y)); }
#endif
using ::fmod;
#if _GLIBCPP_HAVE_FMODL
inline long double
fmod(long double __x, long double __y) { return ::fmodl(__x, __y); }
@ -287,6 +287,8 @@ namespace std
{ return ::fmod(static_cast<double>(__x), static_cast<double>(__y)); }
#endif
using ::frexp;
#if _GLIBCPP_HAVE_FREXPF
inline float
frexp(float __x, int* __exp) { return ::frexpf(__x, __exp); }
@ -295,8 +297,6 @@ namespace std
frexp(float __x, int* __exp) { return ::frexp(__x, __exp); }
#endif
using ::frexp;
#if _GLIBCPP_HAVE_FREXPL
inline long double
frexp(long double __x, int* __exp) { return ::frexpl(__x, __exp); }
@ -306,6 +306,8 @@ namespace std
{ return ::frexp(static_cast<double>(__x), __exp); }
#endif
using ::ldexp;
#if _GLIBCPP_HAVE_LDEXPF
inline float
ldexp(float __x, int __exp) { return ::ldexpf(__x, __exp); }
@ -315,8 +317,6 @@ namespace std
{ return ::ldexp(static_cast<double>(__x), __exp); }
#endif
using ::ldexp;
#if _GLIBCPP_HAVE_LDEXPL
inline long double
ldexp(long double __x, int __exp) { return ::ldexpl(__x, __exp); }
@ -326,6 +326,8 @@ namespace std
{ return ::ldexp(static_cast<double>(__x), __exp); }
#endif
using ::log;
#if _GLIBCPP_HAVE_LOGF
inline float
log(float __x) { return ::logf(__x); }
@ -334,8 +336,6 @@ namespace std
{ return ::log(static_cast<double>(__x)); }
#endif
using ::log;
#if _GLIBCPP_HAVE_LOGL
inline long double
log(long double __x) { return ::logl(__x); }
@ -344,6 +344,8 @@ namespace std
log(long double __x) { return ::log(static_cast<double>(__x)); }
#endif
using ::log10;
#if _GLIBCPP_HAVE_LOG10F
inline float
log10(float __x) { return ::log10f(__x); }
@ -352,8 +354,6 @@ namespace std
log10(float __x) { return ::log10(static_cast<double>(__x)); }
#endif
using ::log10;
#if _GLIBCPP_HAVE_LOG10L
inline long double
log10(long double __x) { return ::log10l(__x); }
@ -362,6 +362,8 @@ namespace std
log10(long double __x) { return ::log10(static_cast<double>(__x)); }
#endif
using ::modf;
#if _GLIBCPP_HAVE_MODFF
inline float
modf(float __x, float* __iptr) { return ::modff(__x, __iptr); }
@ -376,8 +378,6 @@ namespace std
}
#endif
using ::modf;
#if _GLIBCPP_HAVE_MODFL
inline long double
modf(long double __x, long double* __iptr) { return ::modfl(__x, __iptr); }
@ -400,7 +400,9 @@ namespace std
? _Tp(1)/__cmath_power(__x, -__n)
: __cmath_power(__x, __n);
}
using ::pow;
#if _GLIBCPP_HAVE_POWF
inline float
pow(float __x, float __y) { return ::powf(__x, __y); }
@ -410,8 +412,6 @@ namespace std
{ return ::pow(static_cast<double>(__x), static_cast<double>(__y)); }
#endif
using ::pow;
#if _GLIBCPP_HAVE_POWL
inline long double
pow(long double __x, long double __y) { return ::powl(__x, __y); }
@ -421,28 +421,30 @@ namespace std
{ return ::pow(static_cast<double>(__x), static_cast<double>(__y)); }
#endif
inline float
pow(float __x, int __n)
{ return __pow_helper(__x, __n); }
inline double
pow(double __x, int __i)
{ return __pow_helper(__x, __i); }
inline float
pow(float __x, int __n)
{ return __pow_helper(__x, __n); }
inline long double
pow(long double __x, int __n)
{ return __pow_helper(__x, __n); }
using ::sin;
inline float
sin(float __x)
{ return __builtin_sinf(__x); }
using ::sin;
inline long double
sin(long double __x)
{ return __builtin_sinl(__x); }
using ::sinh;
#if _GLIBCPP_HAVE_SINHF
inline float
sinh(float __x) { return ::sinhf(__x); }
@ -451,8 +453,6 @@ namespace std
sinh(float __x) { return ::sinh(static_cast<double>(__x)); }
#endif
using ::sinh;
#if _GLIBCPP_HAVE_SINHL
inline long double
sinh(long double __x) { return ::sinhl(__x); }
@ -461,16 +461,18 @@ namespace std
sinh(long double __x) { return ::sinh(static_cast<double>(__x)); }
#endif
using ::sqrt;
inline float
sqrt(float __x)
{ return __builtin_sqrtf(__x); }
using ::sqrt;
inline long double
sqrt(long double __x)
{ return __builtin_sqrtl(__x); }
using ::tan;
#if _GLIBCPP_HAVE_TANF
inline float
tan(float __x) { return ::tanf(__x); }
@ -479,8 +481,6 @@ namespace std
tan(float __x) { return ::tan(static_cast<double>(__x)); }
#endif
using ::tan;
#if _GLIBCPP_HAVE_TANL
inline long double
tan(long double __x) { return ::tanl(__x); }
@ -489,6 +489,8 @@ namespace std
tan(long double __x) { return ::tan(static_cast<double>(__x)); }
#endif
using ::tanh;
#if _GLIBCPP_HAVE_TANHF
inline float
tanh(float __x) { return ::tanhf(__x); }
@ -497,8 +499,6 @@ namespace std
tanh(float __x) { return ::tanh(static_cast<double>(__x)); }
#endif
using ::tanh;
#if _GLIBCPP_HAVE_TANHL
inline long double
tanh(long double __x) { return ::tanhl(__x); }