[Bug c++/56192] New: global operator new() vs member operator new()

tsoae at mail dot ru gcc-bugzilla@gcc.gnu.org
Sun Feb 3 16:17:00 GMT 2013


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56192

             Bug #: 56192
           Summary: global operator new() vs member operator new()
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: tsoae@mail.ru


g++ 4.8.0 20130127 fails to compile the following code

    #include <cstddef>

    template <class>
        struct A {};

    template <class T>
        A<decltype(new T)> f(int);

    template <class T>
        A<decltype(::new T)> g(int);

    struct X
    {
        void *operator new(std::size_t n, void *);
    };

    int main()
    {
        using type = decltype(g<X>(0));
    }

=====================================================
Using built-in specs.
COLLECT_GCC=bin/g++
COLLECT_LTO_WRAPPER=libexec/gcc/x86_64-linux-gnu/4.8.0/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../gcc-4.8-20130127/configure
--prefix=/mnt/compiles/toolchains/cpp/4.8.0 --disable-nls
--enable-languages=c,c++,go,fortran --enable-shared --enable-linker-build-id
--with-system-zlib --without-included-gettext --enable-threads=posix
--enable-clocale=gnu --enable-libstdcxx-time=yes --enable-gnu-unique-object
--enable-plugin --enable-objc-gc --disable-werror --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu --disable-bootstrap --disable-multilib
--disable-shared --enable-static
Thread model: posix
gcc version 4.8.0 20130127 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-std=c++11' '-v' '-o' 'program' '-mtune=generic'
'-march=x86-64'
 libexec/gcc/x86_64-linux-gnu/4.8.0/cc1plus -quiet -v -imultilib . -imultiarch
x86_64-linux-gnu -D_GNU_SOURCE source.cpp -quiet -dumpbase source.cpp
-mtune=generic -march=x86-64 -auxbase source -std=c++11 -version -o
/tmp/ccKToF0B.s
GNU C++ (GCC) version 4.8.0 20130127 (experimental) (x86_64-linux-gnu)
    compiled by GNU C version 4.7.2, GMP version 5.0.2, MPFR version 3.1.0-p3,
MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory
"lib/gcc/x86_64-linux-gnu/4.8.0/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 lib/gcc/x86_64-linux-gnu/4.8.0/../../../../include/c++/4.8.0

lib/gcc/x86_64-linux-gnu/4.8.0/../../../../include/c++/4.8.0/x86_64-linux-gnu/.
 lib/gcc/x86_64-linux-gnu/4.8.0/../../../../include/c++/4.8.0/backward
 lib/gcc/x86_64-linux-gnu/4.8.0/include
 /usr/local/include
 include
 lib/gcc/x86_64-linux-gnu/4.8.0/include-fixed
 x86_64-linux-gnu
 /usr/include
End of search list.
GNU C++ (GCC) version 4.8.0 20130127 (experimental) (x86_64-linux-gnu)
    compiled by GNU C version 4.7.2, GMP version 5.0.2, MPFR version 3.1.0-p3,
MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c50b4a9e751f2a9ab933b25f6962a9bf
source.cpp: In function 'int main()':
source.cpp:19:33: error: no matching function for call to 'g(int)'
     using type = decltype(g<X>(0));

                                 ^
source.cpp:19:33: note: candidate is:
source.cpp:10:26: note: template<class T> A<decltype (new T)> g(int)
     A<decltype(::new T)> g(int);

                          ^
source.cpp:10:26: note:   template argument deduction/substitution failed:
source.cpp: In substitution of 'template<class T> A<decltype (new T)> g(int)
[with T = <missing>]':
source.cpp:19:33:   required from here
source.cpp:10:26: error: no matching function for call to 'X::operator
new(sizetype)'
source.cpp:10:26: note: candidate is:
source.cpp:14:11: note: static void* X::operator new(std::size_t, void*)
     void *operator new(std::size_t n, void *);

           ^
source.cpp:14:11: note:   candidate expects 2 arguments, 1 provided
source.cpp:19:33: error: no matching function for call to 'g(int)'
     using type = decltype(g<X>(0));

                                 ^
source.cpp:19:33: note: candidate is:
source.cpp:10:26: note: template<class T> A<decltype (new T)> g(int)
     A<decltype(::new T)> g(int);

                          ^
source.cpp:10:26: note:   template argument deduction/substitution failed:
source.cpp: In substitution of 'template<class T> A<decltype (new T)> g(int)
[with T = <missing>]':
source.cpp:19:33:   required from here
source.cpp:10:26: error: no matching function for call to 'X::operator
new(sizetype)'
source.cpp:10:26: note: candidate is:
source.cpp:14:11: note: static void* X::operator new(std::size_t, void*)
     void *operator new(std::size_t n, void *);

           ^
source.cpp:14:11: note:   candidate expects 2 arguments, 1 provided
=====================================================

The compiler ignores the presence of :: before new in the declaration of g and
tries to find X::operator new() there. If we remove the declaration of f, the
lookup for operator new() will be performed correctly.

In my original code similar constructs are used as SFINAE triggers, so I can't
just replace such decltype specifiers with well-known pointer types.

See also examples in
http://liveworkspace.org/code/3h5UIC$1
[You can switch between examples by means of the "changes" switcher]



More information about the Gcc-bugs mailing list