The following patch has lived on mainline for 6 months and has not generated any issues there. We've also been using it on our 4.8 based IBM branch with no problems either, so I'd like to ask for permission to backport this fix to the FSF 4.8 branch. This will bring GCC into compliance with CLANG and the XL C++ compilers with respect to this bug. I know the XL C++ compiler specifically will not accept the definition in the tr1/cmath header file, therefore it is not able to compile any program that uses that header.
Since there are a few 4.8 based distro compilers coming, I'd like to fix this in the FSF branch so they'll all get the fix automatically. Ok for the FSF 4.8 branch once my bootstrap and regtesting are complete (using powerpc64-linux)? Peter libstdc++-v3/ Backport from mainline 2013-08-01 Fabien Chêne <fab...@gcc.gnu.org> PR c++/54537 * include/tr1/cmath: Remove pow(double,double) overload, remove a duplicated comment about DR 550. Add a comment to explain the issue. * testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc: New. gcc/cp/ Back port from mainline 2013-08-01 Fabien Chêne <fab...@gcc.gnu.org> PR c++/54537 * cp-tree.h: Check OVL_USED with OVERLOAD_CHECK. * name-lookup.c (do_nonmember_using_decl): Make sure we have an OVERLOAD before calling OVL_USED. Call diagnose_name_conflict instead of issuing an error without mentioning the conflicting declaration. gcc/testsuite/ Back port from mainline 2013-08-01 Fabien Chêne <fab...@gcc.gnu.org> Peter Bergner <berg...@vnet.ibm.com> PR c++/54537 * g++.dg/overload/using3.C: New. * g++.dg/overload/using2.C: Adjust. * g++.dg/lookup/using9.C: Likewise. Index: libstdc++-v3/include/tr1/cmath =================================================================== --- libstdc++-v3/include/tr1/cmath (revision 208748) +++ libstdc++-v3/include/tr1/cmath (working copy) @@ -846,10 +846,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION nexttoward(_Tp __x, long double __y) { return __builtin_nexttoward(__x, __y); } - // DR 550. What should the return type of pow(float,int) be? - // NB: C++0x and TR1 != C++03. - // using std::pow; - inline float remainder(float __x, float __y) { return __builtin_remainderf(__x, __y); } @@ -985,9 +981,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 550. What should the return type of pow(float,int) be? // NB: C++0x and TR1 != C++03. - inline double - pow(double __x, double __y) - { return std::pow(__x, __y); } + + // The std::tr1::pow(double, double) overload cannot be provided + // here, because it would clash with ::pow(double,double) declared + // in <math.h>, if <tr1/math.h> is included at the same time (raised + // by the fix of PR c++/54537). It is not possible either to use the + // using-declaration 'using ::pow;' here, because if the user code + // has a 'using std::pow;', it would bring the pow(*,int) averloads + // in the tr1 namespace, which is undesirable. Consequently, the + // solution is to forward std::tr1::pow(double,double) to + // std::pow(double,double) via the templatized version below. See + // the discussion about this issue here: + // http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01278.html inline float pow(float __x, float __y) Index: libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc =================================================================== --- libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc (revision 0) +++ libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc (revision 0) @@ -0,0 +1,33 @@ +// { dg-do compile } + +// Copyright (C) 2013 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <cmath> +using std::pow; +#include <tr1/cmath> +#include <testsuite_tr1.h> + +void +test01() +{ + using namespace __gnu_test; + + float x = 2080703.375F; + check_ret_type<float>(std::pow(x, 2)); + check_ret_type<double>(std::tr1::pow(x, 2)); +} Index: gcc/testsuite/g++.dg/lookup/using9.C =================================================================== --- gcc/testsuite/g++.dg/lookup/using9.C (revision 208748) +++ gcc/testsuite/g++.dg/lookup/using9.C (working copy) @@ -21,11 +21,11 @@ void h() f('h'); f(1); // { dg-error "ambiguous" } // { dg-message "candidate" "candidate note" { target *-*-* } 22 } - void f(int); // { dg-error "previous using declaration" } + void f(int); // { dg-error "previous declaration" } } void m() { void f(int); - using B::f; // { dg-error "already declared" } + using B::f; // { dg-error "previous declaration" } } Index: gcc/testsuite/g++.dg/overload/using3.C =================================================================== --- gcc/testsuite/g++.dg/overload/using3.C (revision 0) +++ gcc/testsuite/g++.dg/overload/using3.C (revision 0) @@ -0,0 +1,16 @@ +// { dg-do compile } + +namespace a +{ + void f(int); +} + +namespace b +{ + void f(int); // { dg-message "previous" } + void g() + { + f (3); + } + using a::f; // { dg-error "conflicts" } +} Index: gcc/testsuite/g++.dg/overload/using2.C =================================================================== --- gcc/testsuite/g++.dg/overload/using2.C (revision 208748) +++ gcc/testsuite/g++.dg/overload/using2.C (working copy) @@ -45,7 +45,7 @@ using std::C1; extern "C" void exit (int) throw (); extern "C" void *malloc (__SIZE_TYPE__) throw () __attribute__((malloc)); - void abort (void) throw (); + void abort (void) throw (); // { dg-message "previous" } void _exit (int) throw (); // { dg-error "conflicts" "conflicts" } // { dg-message "void _exit" "_exit" { target *-*-* } 49 } @@ -54,14 +54,14 @@ using std::C1; // { dg-message "void C1" "C1" { target *-*-* } 53 } extern "C" void c2 (void) throw (); - void C2 (void) throw (); + void C2 (void) throw (); // { dg-message "previous" } int C3 (int) throw (); using std::malloc; -using std::abort; // { dg-error "already declared" } +using std::abort; // { dg-error "conflicts" } using std::c2; -using std::C2; // { dg-error "already declared" } +using std::C2; // { dg-error "conflicts" } using std::c3; using other::c3; using std::C3; using other::C3; Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 208748) +++ gcc/cp/cp-tree.h (working copy) @@ -331,7 +331,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t /* If set, this was imported in a using declaration. This is not to confuse with being used somewhere, which is not important for this node. */ -#define OVL_USED(NODE) TREE_USED (NODE) +#define OVL_USED(NODE) TREE_USED (OVERLOAD_CHECK (NODE)) /* If set, this OVERLOAD was created for argument-dependent lookup and can be freed afterward. */ #define OVL_ARG_DEPENDENT(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE)) Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 208748) +++ gcc/cp/name-lookup.c (working copy) @@ -2286,8 +2286,7 @@ push_overloaded_decl_1 (tree decl, int f && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), TYPE_ARG_TYPES (TREE_TYPE (decl))) && ! decls_match (fn, decl)) - error ("%q#D conflicts with previous using declaration %q#D", - decl, fn); + diagnose_name_conflict (decl, fn); dup = duplicate_decls (decl, fn, is_friend); /* If DECL was a redeclaration of FN -- even an invalid @@ -2519,7 +2518,7 @@ do_nonmember_using_decl (tree scope, tre if (new_fn == old_fn) /* The function already exists in the current namespace. */ break; - else if (OVL_USED (tmp1)) + else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1)) continue; /* this is a using decl */ else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) @@ -2534,7 +2533,7 @@ do_nonmember_using_decl (tree scope, tre break; else { - error ("%qD is already declared in this scope", name); + diagnose_name_conflict (new_fn, old_fn); break; } }