This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Builtins and C++ and such (take 2)



> >> The new builtin_function needs to say what all of its parameters are
> >> in its comments.  Roger, would you commit both patches, with that
> >> change, or -- if you do not have checkin privileges -- send me an
> >> email with the combined patch, including that change, and then I'll
> >> be happy to apply it for you?
> >
> > My apologies.
>
> Please let me know how your efforts to get the whole thing working
> proceed.


Here's the full version of the patch to enable built-ins in g++ in
both the global and std namespaces.  This has been tested with a
full "make bootstrap" and "make -k check" on i686-pc-linux-gnu with
no new regressions.  [I'm having CVS bootstrap problems on my
other platforms at the moment].

The patch below also includes four new g++ test cases.  The first
one checks that the necessary errors are generated if the builtins
aren't used without being prototyped.  The remaining three check
that builtins are recognized and optimized.

The very tiny fly-in-the-ointment is the trivial libstdc++-v3
change to "cmath".  If the first declaration of a builtin identifier
in the std namespace doesn't have the expected function type, the
builtin is disabled.  Simply moving the "using"s of the double forms
before defining the float variants fixes the problem.  Ben is this
change OK with the libstdc++ folks?


Is this solution OK for mainline?


2002-03-23  Roger Sayle  <roger@eyesopen.com>
	* decl.c (cxx_init_decl_processing): Re-enable built-in functions
	in the g++ front-end.
	(duplicate_decl): Allow redefinition of anticipated built-ins.
	(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-23  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-23  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.


diff -c3pr gcc/gcc/cp/decl.c patch/gcc/cp/decl.c
*** gcc/gcc/cp/decl.c	Tue Mar 19 21:31:30 2002
--- patch/gcc/cp/decl.c	Sat Mar 23 11:49:03 2002
*************** static tree lookup_tag PARAMS ((enum tre
*** 87,92 ****
--- 87,94 ----
  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,
*************** duplicate_decls (newdecl, olddecl)
*** 3145,3150 ****
--- 3147,3156 ----
      {
        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.  */
*************** duplicate_decls (newdecl, olddecl)
*** 3172,3178 ****
  	}
        else if (!types_match)
  	{
! 	  if ((DECL_EXTERN_C_P (newdecl)
  	       && DECL_EXTERN_C_P (olddecl))
  	      || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
  			    TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
--- 3178,3187 ----
  	}
        else if (!types_match)
  	{
!           /* 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))))
*************** lookup_namespace_name (namespace, name)
*** 5507,5513 ****
        /* 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;
      }

    error ("`%D' undeclared in namespace `%D'", name, namespace);
--- 5516,5527 ----
        /* 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);
!
!       /* 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);
*************** select_decl (binding, flags)
*** 5786,5799 ****
    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. */
--- 5800,5805 ----
*************** unqualified_namespace_lookup (name, flag
*** 5843,5851 ****
  	*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);

        /* Add all _DECLs seen through local using-directives. */
        for (level = current_binding_level;
--- 5849,5869 ----
  	*spacesp = tree_cons (scope, NULL_TREE, *spacesp);
        val = binding_for_name (name, scope);

!       /* 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;
*************** cxx_init_decl_processing ()
*** 6435,6446 ****
        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;

--- 6453,6458 ----
*************** cp_make_fname_decl (id, type_dep)
*** 6704,6713 ****
    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.

     CLASS and CODE tell later passes how to compile calls to this function.
     See tree.h for possible values.
--- 6716,6724 ----
    return decl;
  }

! /* 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.
*************** cp_make_fname_decl (id, type_dep)
*** 6715,6724 ****
     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;
--- 6726,6736 ----
     If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
     the name to be called if we can't opencode the function.  */

! 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;
*************** builtin_function (name, type, code, clas
*** 6726,6748 ****
    tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
    DECL_BUILT_IN_CLASS (decl) = class;
    DECL_FUNCTION_CODE (decl) = code;

    /* 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
--- 6738,6750 ----
    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;

    pushdecl (decl);

    /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
       we cannot change DECL_ASSEMBLER_NAME until we have installed this
*************** builtin_function (name, type, code, clas
*** 6762,6767 ****
--- 6764,6802 ----
    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.  */

diff -c3pr gcc/gcc/cp/decl2.c patch/gcc/cp/decl2.c
*** gcc/gcc/cp/decl2.c	Wed Mar 20 21:08:25 2002
--- patch/gcc/cp/decl2.c	Sat Mar 23 00:29:58 2002
*************** ambiguous_decl (name, old, new, flags)
*** 4176,4181 ****
--- 4176,4186 ----
          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;
*************** do_nonmember_using_decl (scope, name, ol
*** 4928,4933 ****
--- 4933,4947 ----
  	      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.  */
diff -c3pr gcc/gcc/cp/lex.c patch/gcc/cp/lex.c
*** gcc/gcc/cp/lex.c	Wed Mar 20 21:08:25 2002
--- patch/gcc/cp/lex.c	Sat Mar 23 00:29:09 2002
*************** do_scoped_id (token, parsing)
*** 1325,1331 ****
      id = IDENTIFIER_GLOBAL_VALUE (token);
    if (parsing && yychar == YYEMPTY)
      yychar = yylex ();
!   if (! id)
      {
        if (processing_template_decl)
  	{
--- 1325,1332 ----
      id = IDENTIFIER_GLOBAL_VALUE (token);
    if (parsing && yychar == YYEMPTY)
      yychar = yylex ();
!   if (!id || (TREE_CODE (id) == FUNCTION_DECL
! 	      && DECL_ANTICIPATED (id)))
      {
        if (processing_template_decl)
  	{
*** gcc/libstdc++-v3/include/c_std/std_cmath.h	Sun Feb  3 13:59:25 2002
--- patch/libstdc++-v3/include/c_std/std_cmath.h	Sat Mar 23 17:09:38 2002
***************
*** 1,6 ****
  // -*- C++ -*- C math library.

! // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
  // software; you can redistribute it and/or modify it under the
--- 1,7 ----
  // -*- C++ -*- C math library.

! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
! // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
  // software; you can redistribute it and/or modify it under the
*************** namespace std
*** 99,104 ****
--- 100,107 ----
    abs(long double __x)
    { return __builtin_fabsl(__x); }

+   using ::acos;
+
  #if _GLIBCPP_HAVE_ACOSF
    inline float
    acos(float __x) { return ::acosf(__x); }
*************** namespace std
*** 107,114 ****
    acos(float __x) { return ::acos(static_cast<double>(__x)); }
  #endif

-   using ::acos;
-
  #if _GLIBCPP_HAVE_ACOSL
    inline long double
    acos(long double __x) { return ::acosl(__x); }
--- 110,115 ----
*************** namespace std
*** 117,122 ****
--- 118,125 ----
    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); }
*************** namespace std
*** 125,132 ****
    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); }
--- 128,133 ----
*************** namespace std
*** 135,140 ****
--- 136,143 ----
    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); }
*************** namespace std
*** 143,150 ****
    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); }
--- 146,151 ----
*************** namespace std
*** 153,158 ****
--- 154,161 ----
    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); }
*************** namespace std
*** 162,169 ****
    { 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); }
--- 165,170 ----
*************** namespace std
*** 173,178 ****
--- 174,181 ----
    { 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); }
*************** namespace std
*** 181,188 ****
    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); }
--- 184,189 ----
*************** namespace std
*** 191,206 ****
    ceil(long double __x) { return ::ceil(static_cast<double>(__x)); }
  #endif

    inline float
    cos(float __x)
    { return __builtin_cosf(__x); }

-   using ::cos;
-
    inline long double
    cos(long double __x)
    { return __builtin_cosl(__x); }

  #if _GLIBCPP_HAVE_COSHF
    inline float
    cosh(float __x) { return ::coshf(__x); }
--- 192,209 ----
    ceil(long double __x) { return ::ceil(static_cast<double>(__x)); }
  #endif

+   using ::cos;
+
    inline float
    cos(float __x)
    { return __builtin_cosf(__x); }

    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); }
*************** namespace std
*** 209,216 ****
    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); }
--- 212,217 ----
*************** namespace std
*** 219,224 ****
--- 220,227 ----
    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); }
*************** namespace std
*** 227,234 ****
    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); }
--- 230,235 ----
*************** namespace std
*** 237,252 ****
    exp(long double __x) { return ::exp(static_cast<double>(__x)); }
  #endif

    inline float
    fabs(float __x)
    { return __builtin_fabsf(__x); }

-   using ::fabs;
-
    inline long double
    fabs(long double __x)
    { return __builtin_fabsl(__x); }

  #if _GLIBCPP_HAVE_FLOORF
    inline float
    floor(float __x) { return ::floorf(__x); }
--- 238,255 ----
    exp(long double __x) { return ::exp(static_cast<double>(__x)); }
  #endif

+   using ::fabs;
+
    inline float
    fabs(float __x)
    { return __builtin_fabsf(__x); }

    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); }
*************** namespace std
*** 255,262 ****
    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); }
--- 258,263 ----
*************** namespace std
*** 265,270 ****
--- 266,273 ----
    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); }
*************** namespace std
*** 274,281 ****
    { 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); }
--- 277,282 ----
*************** namespace std
*** 285,290 ****
--- 286,293 ----
    { 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); }
*************** namespace std
*** 293,300 ****
    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); }
--- 296,301 ----
*************** namespace std
*** 304,309 ****
--- 305,312 ----
    { 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); }
*************** namespace std
*** 313,320 ****
    { 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); }
--- 316,321 ----
*************** namespace std
*** 324,329 ****
--- 325,332 ----
    { return ::ldexp(static_cast<double>(__x), __exp); }
  #endif

+   using ::log;
+
  #if _GLIBCPP_HAVE_LOGF
    inline float
    log(float __x) { return ::logf(__x); }
*************** namespace std
*** 332,339 ****
    { return ::log(static_cast<double>(__x)); }
  #endif

-   using ::log;
-
  #if _GLIBCPP_HAVE_LOGL
    inline long double
    log(long double __x) { return ::logl(__x); }
--- 335,340 ----
*************** namespace std
*** 342,347 ****
--- 343,350 ----
    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); }
*************** namespace std
*** 350,357 ****
    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); }
--- 353,358 ----
*************** namespace std
*** 360,365 ****
--- 361,368 ----
    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); }
*************** namespace std
*** 374,381 ****
    }
  #endif

-   using ::modf;
-
  #if _GLIBCPP_HAVE_MODFL
    inline long double
    modf(long double __x, long double* __iptr) { return ::modfl(__x, __iptr); }
--- 377,382 ----
*************** namespace std
*** 399,404 ****
--- 400,407 ----
          : __cmath_power(__x, __n);
      }

+   using ::pow;
+
  #if _GLIBCPP_HAVE_POWF
    inline float
    pow(float __x, float __y) { return ::powf(__x, __y); }
*************** namespace std
*** 408,415 ****
    { 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); }
--- 411,416 ----
*************** namespace std
*** 431,446 ****
    pow(long double __x, int __n)
    { return __pow_helper(__x, __n); }

    inline float
    sin(float __x)
    { return __builtin_sinf(__x); }

-   using ::sin;
-
    inline long double
    sin(long double __x)
    { return __builtin_sinl(__x); }

  #if _GLIBCPP_HAVE_SINHF
    inline float
    sinh(float __x) { return ::sinhf(__x); }
--- 432,449 ----
    pow(long double __x, int __n)
    { return __pow_helper(__x, __n); }

+   using ::sin;
+
    inline float
    sin(float __x)
    { return __builtin_sinf(__x); }

    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); }
*************** namespace std
*** 449,456 ****
    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); }
--- 452,457 ----
*************** namespace std
*** 459,474 ****
    sinh(long double __x) { return ::sinh(static_cast<double>(__x)); }
  #endif

    inline float
    sqrt(float __x)
    { return __builtin_sqrtf(__x); }

-   using ::sqrt;
-
    inline long double
    sqrt(long double __x)
    { return __builtin_sqrtl(__x); }

  #if _GLIBCPP_HAVE_TANF
    inline float
    tan(float __x) { return ::tanf(__x); }
--- 460,477 ----
    sinh(long double __x) { return ::sinh(static_cast<double>(__x)); }
  #endif

+   using ::sqrt;
+
    inline float
    sqrt(float __x)
    { return __builtin_sqrtf(__x); }

    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); }
*************** namespace std
*** 477,484 ****
    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); }
--- 480,485 ----
*************** namespace std
*** 487,492 ****
--- 488,495 ----
    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); }
*************** namespace std
*** 495,502 ****
    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); }
--- 498,503 ----
*** /dev/null	Thu Aug 30 14:30:55 2001
--- builtins5.C	Wed Mar 20 21:55:21 2002
***************
*** 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
+ }
*** /dev/null	Thu Aug 30 14:30:55 2001
--- builtins6.C	Thu Mar 21 14:49:57 2002
***************
*** 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;
+ }
+
*** /dev/null	Thu Aug 30 14:30:55 2001
--- builtins7.C	Thu Mar 21 14:50:08 2002
***************
*** 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;
+ }
*** /dev/null	Thu Aug 30 14:30:55 2001
--- builtins8.C	Thu Mar 21 14:50:23 2002
***************
*** 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;
+ }
+


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]