[Webkit-unassigned] [Bug 59249] New: Colliding isinf/isnan between C99 and C++0x with GCC 4.6.0

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Apr 22 15:28:23 PDT 2011


https://bugs.webkit.org/show_bug.cgi?id=59249

           Summary: Colliding isinf/isnan between C99 and C++0x with GCC
                    4.6.0
           Product: WebKit
           Version: 528+ (Nightly build)
          Platform: PC
        OS/Version: Mac OS X 10.5
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: Tools / Tests
        AssignedTo: webkit-unassigned at lists.webkit.org
        ReportedBy: xan.lopez at gmail.com


Compilation of WebKit with GCC 4.6.0 C++0x mode fails for various reasons, but the only interesting/complicated one is related to the new isnan/isinf functions introduced in C++0x. Trying to compile with -std=c++0x gives the following:

In file included from ../../Source/JavaScriptCore/runtime/JSValue.h:31:0,
                 from ../../Source/JavaScriptCore/runtime/CallData.h:32,
                 from ../../Source/JavaScriptCore/runtime/Executable.h:29,
                 from ../../Source/JavaScriptCore/bytecode/EvalCodeCache.h:32,
                 from ../../Source/JavaScriptCore/bytecode/CodeBlock.h:33,
                 from ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:33,
                 from ../../Source/JavaScriptCore/jsc.cpp:25:
../../Source/JavaScriptCore/wtf/MathExtras.h:243:12: error: ‘isinf’ is already declared in this scope
../../Source/JavaScriptCore/wtf/MathExtras.h:244:12: error: ‘isnan’ is already declared in this scope

This happens because in C++0x mode (but not otherwise) there's a conflicting extern declaration in bits/mathcalls.h, something like:

extern int isinf(double);

so we get a collision in the global namespace. According to the C++ standard it's undefined whether the functions will be present in the global namespace or not, so I don't think this can be considered a bug in GCC.

We can protect those two lines in MathExtras.h with a "am I using C++0x in GCC" #ifdef, like:

diff --git a/Source/JavaScriptCore/wtf/MathExtras.h b/Source/JavaScriptCore/wtf/MathExtras.h
index fac187c..78eb467 100644
--- a/Source/JavaScriptCore/wtf/MathExtras.h
+++ b/Source/JavaScriptCore/wtf/MathExtras.h
@@ -240,8 +240,10 @@ inline int clampToInteger(unsigned value)

 #if !COMPILER(MSVC) && !(COMPILER(RVCT) && PLATFORM(BREWMP)) && !OS(SOLARIS) && !OS(SYMBIAN)
 using std::isfinite;
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
 using std::isinf;
 using std::isnan;
+#endif
 using std::signbit;
 #endif

but then the next problem arises:

../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp: In member function ‘JSC::RegisterID* JSC::BytecodeGenerator::emitLoad(JSC::RegisterID*, double)’:
../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:1109:21: error: call of overloaded ‘isnan(double&)’ is ambiguous
../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:1109:21: note: candidates are:
/usr/include/bits/mathcalls.h:235:1: note: int isnan(double)
/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../include/c++/4.6.0/cmath:558:3: note: bool std::isnan(long double)
/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../include/c++/4.6.0/cmath:554:3: note: bool std::isnan(double)
/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../include/c++/4.6.0/cmath:550:3: note: bool std::isnan(float)

The issue here is that this file (and others) have a "using namespace std;" and use isinf/isnan without the std:: prefix, so the compiler cannot tell whether the user wants the C99 version in the global namespace or the C++0x version in std. If the line is removed the ambiguity is gone, although now we'll be using the C99 functions if we just write "isinf" (we'd use the C++ ones if we wrote std::isinf). This is not ideal, I suppose, but at least it works.

I think with some changes in WebKit we could get a better solution, namely one that ends up using the C++ methods throughout *and* compiles correctly under GCC 4.6.0 C++0x. We can:

- Remove the "using std::isinf/isnan/etc" from MathExtras.h for GCC C++0x, at least.
- Remove math.h from all of WebKit
- Change all uses of unprefixed isnan/isinf in WebKit to be "std::isnan/isinf". This way the function call is not ambiguous and we get the C++ version, as we want. This would not only work in modern GCC versions, but also in the old ones and the ARM compiler, where the cmath functions are never present in the global namespace.

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the webkit-unassigned mailing list