https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94888

            Bug ID: 94888
           Summary: segment fault
           Product: gcc
           Version: 5.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: chunqiu1234 at foxmail dot com
  Target Milestone: ---

There is some problems with my project use g++ in linuxOS. So I extract the
main.cpp  from my project. And when I run the program compiled with g++ , it
always reports segment fault. the same program I compiled with Microsoft VC++
works well. So I want to know whether there is a bug with g++? 


my g++ version:

z@sd:~$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-5 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)


SOURCE CODE
main.cpp:


//RemoveRef
template<typename _Tp>
struct RemoveRef
{ typedef _Tp   type; };

template<typename _Tp>
struct RemoveRef<_Tp&>
{ typedef _Tp   type; };

template<typename _Tp>
struct RemoveRef<_Tp&&>
{ typedef _Tp   type; };


//RValue
template<typename _Tp>
typename RemoveRef<_Tp>::type&& RValueRef(_Tp&& __t)
{ return static_cast<typename  RemoveRef<_Tp>::type&&>(__t); }


//Forward
template<typename _Tp>
_Tp&&
Forward(typename RemoveRef<_Tp>::type& __t)
{ return static_cast<_Tp&&>(__t); }


template<typename _Tp>
_Tp&&
Forward(typename RemoveRef<_Tp>::type&& __t)
{ return static_cast<_Tp&&>(__t); }



//RemoveConst
template <typename T>
struct RemoveConst{
    typedef  T  type;
};

template <typename T>
struct RemoveConst<T const &>{
    typedef  T&  type;
};

template <typename T>
struct RemoveConst<T const *>{
    typedef  T* type;
};


template <typename T>
struct RemoveConst<const T>{
    typedef  T  type;
};

template<typename _Tp>
typename RemoveConst<_Tp>::type NonConst(_Tp&& __t)
{ return (typename RemoveConst<_Tp>::type)(__t); }

template<typename _Tp>
typename RemoveConst<_Tp>::type* NonConst(_Tp* __t)
{ return (typename RemoveConst<_Tp>::type*)(__t); }






template <typename Ret,
          typename ... Arg >
class IFunction{
public:
    virtual Ret call(Arg... args) = 0;
    virtual ~IFunction() {};
};


template <typename T,
          typename Ret,
          typename ... Arg >
class FunctionImpl
        : public IFunction <Ret, Arg ...>{
public:
    virtual Ret call(Arg... args) {
        return t(args...);
    }

    template <typename Ty>
    FunctionImpl(Ty&& t_) : t(Forward<Ty>(t_)) {}

private:
    T t;
};



template <typename Ret,
          typename ... Arg >
class FunctionBridger{
public:
    template <typename T>
    FunctionBridger(T&& func_) :
        func(new FunctionImpl<typename RemoveRef<T>::type, Ret, Arg
...>(Forward<T>(func_) ) )
    {
    }

    FunctionBridger(FunctionBridger&& o){
        func = o.func, o.func = 0;
    }
    ~FunctionBridger() {func ? (delete  func, 1) : 0;}

    Ret operator ()(Arg... args) {
        return  func->call(args...);
    }

private:
    IFunction<Ret, Arg ...> *func;
};


template <typename T>
struct FunctionType{

};


template <typename Ret,
          typename ... Arg >
struct FunctionType<Ret(Arg ...)>{
    typedef  FunctionBridger<Ret, Arg...> type;
};





template <typename T>
class Function
        : public FunctionType<T>::type{
public:
    template <typename Ty>
    Function( Ty&& func) : FunctionType<T>::type(Forward<Ty>(func)) { }

    ~Function() {};

private:
    template <typename Ty>
    void operator = (Ty&& func);
};



static int f(char a){
    return  a+1;
}


struct F{
    int operator ()(char a){
        return a+2;
    }
    int operator ()(char a) const{
        return a+3;
    }
};



int main(int argc, char *argv[])
{
    Function<int(char)> func = &f;
    char ret = func('a');    //'b'

    F f1;
    Function<int(char)> func1 =  f1;
    ret = func1('a'); //c

    const F f2;
    Function<int(char)> func2 =  f2;
    ret = func2('a'); //'d'
    return 0;
}

Reply via email to