While working on a policy-based smart pointer I discovered that
copy-initialization, base-from-derived, using Colvin-Gibbons trick, does not
work for std::auto ptr with gcc. It also reproduces with OpenSUSE 11.0 with gcc
4.3.1 (now I am on 10.3 with gcc 4.2.1).

The technique and test is described in Fixing auto_ptr:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1128.pdf


The options given when GCC was configured/built:
gcc -v
Using built-in specs.
Target: i586-suse-linux
Configured with: ../configure --enable-threads=posix --prefix=/usr
--with-local-prefix=/usr/local --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib
--enable-languages=c,c++,objc,fortran,obj-c++,java,ada
--enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.2.1
--enable-ssp --disable-libssp --disable-libgcj --with-slibdir=/lib
--with-system-zlib --enable-shared --enable-__cxa_atexit
--enable-libstdcxx-allocator=new --disable-libstdcxx-pch --program-suffix=-4.2
--enable-version-specific-runtime-libs --without-system-libunwind
--with-cpu=generic --host=i586-suse-linux
Thread model: posix
gcc version 4.2.1 (SUSE Linux)


The complete command line that triggers the bug (from KDevelop output):
g++ -DHAVE_CONFIG_H -I. -I..
-I/home/cristia/Work/test_auto_ptr_colvin_gibbons/src -O0 -g3 -MT
test_auto_ptr_colvin_gibbons.o -MD -MP -MF
.deps/test_auto_ptr_colvin_gibbons.Tpo -c -o test_auto_ptr_colvin_gibbons.o
/home/cristia/Work/test_auto_ptr_colvin_gibbons/src/test_auto_ptr_colvin_gibbons.cpp


The compiler output:
/home/cristia/Work/test_auto_ptr_colvin_gibbons/src/test_auto_ptr_colvin_gibbons.cpp:
In function 'int main(int, char**)':
/home/cristia/Work/test_auto_ptr_colvin_gibbons/src/test_auto_ptr_colvin_gibbons.cpp:72:
error: no matching function for call to
'std::auto_ptr<Base>::auto_ptr(std::auto_ptr<Base>)'
/usr/include/c++/4.2.1/memory:349: note: candidates are:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = Base]
/usr/include/c++/4.2.1/memory:212: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = Base, _Tp =
Base]
/usr/include/c++/4.2.1/memory:199: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = Base]
/home/cristia/Work/test_auto_ptr_colvin_gibbons/src/test_auto_ptr_colvin_gibbons.cpp:72:
error: initializing argument 1 of 'void UseBase(AutoPtrBase)' from result of
'std::auto_ptr<_Tp>::operator std::auto_ptr<_Tp1>() [with _Tp1 = Base, _Tp =
Derived]'
gmake[2]: *** [test_auto_ptr_colvin_gibbons.o] Error 1
gmake[2]: Target `all' not remade because of errors.
gmake[2]: Nothing to be done for `all-am'.
gmake[1]: *** [all-recursive] Error 1
gmake: *** [all] Error 2
*** Exited with status: 2 ***


Test program:


#include <memory>


class Base {
public:
        virtual ~Base() {}

        virtual void Hello() {}
};


class Derived: public Base {
public:
        virtual void Hello() {}
};


typedef std::auto_ptr<int> AutoPtrInt;
typedef std::auto_ptr<Base> AutoPtrBase;
typedef std::auto_ptr<Derived> AutoPtrDerived;


AutoPtrInt CreateInt() { return AutoPtrInt(new int); }
void UseInt(AutoPtrInt ptr) { (*ptr)++; };

AutoPtrDerived CreateDerived() { return AutoPtrDerived(new Derived); }
void UseBase(AutoPtrBase ptr) { ptr->Hello(); }


int main(int argc, char *argv[]) {
        {
                AutoPtrInt api(CreateInt());    // 1. Direct-initialization,
same type: OK
        }

        {
                UseInt(CreateInt());    // 2. Copy-initialization, same type:
OK
        }

        {
                AutoPtrBase apb(CreateDerived());       // 3.
Direct-initialization, base-from-derived: OK
        }

        {
                // 4. Copy-initialization, base-from-derived: Does not
compile!!!
                UseBase(CreateDerived());

                // Quick workaround
                UseBase(AutoPtrBase(CreateDerived()));
        }

        return 0;
}


Thanks,
    Cristian


-- 
           Summary: std::auto_prtr copy-initialization, base-from-derived
                    (Colvin-Gibbons trick) does not work
           Product: gcc
           Version: 4.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: cristian_anita at yahoo dot com
 GCC build triplet: i586-suse-linux
  GCC host triplet: i586-suse-linux
GCC target triplet: i586-suse-linux


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

Reply via email to