g ++ 4.2:内部编译器错误:在make_thunk中,在cp / method.c:129

时间:2013-03-18 18:45:05

标签: c++ compiler-errors g++

我已在http://www.cplusplus.com/forum/general/96128/上提出这个问题,但无济于事。

是否有人遇到过与g ++ 4.2相同的错误:internal compiler error: in make_thunk, at cp/method.c:129

我认为不需要包含示例代码。相应的代码在其他几个较新的g ++版本以及clang ++上编译时没有警告和错误。这是完全正确的,并且在GCC的bugzilla中提到了bug(甚至几次,因为它似乎经常重复),但没有提供解决方法。

请不要告诉我们使用更新的g ++。我必须在Ubuntu Hardy附带的g ++上编译它,所以我无法更改编译器。主要开发是在Ubuntu Precise上完成的,但我需要让它与Hardy保持兼容。

我不知道thunk应该是什么,我只怀疑它与covariants和/或多重继承有关。此外,我还有几个类似的结构化头文件,所有这些都编译得很好,尽管唯一的变化是名称是类的名称而我没有目标,因为Hardy上的编译器错误而改变它。

另一个事实是,它发生在包含时间。

In file included from /home/heiko/hgl/src/compiler/compilerprojectfactory.cpp:18:
/home/heiko/hgl/src/compiler/compilertype.h: In instantiation of 'HGL::Compiler::CompilerType<HGL::Vector2D, HGL::Compiler::CompilerBase>':
/home/heiko/hgl/src/compiler/compilervector2d.h:23: instantiated from here
/home/heiko/hgl/src/compiler/compilertype.h:22: internal compiler error: in make_thunk, at cp/method.c:129
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see <URL:file:///usr/share/doc/gcc-4.2/README.Bug

编辑:这里导致错误的标题:

#include "compilertype.h"
#include "vector2d.h"

namespace HGL {

class Vector2D;

namespace Compiler {

/**
    @author Heiko Schäfer <heiko@rangun.de>
*/
class _LOCAL Vector2D : public Compiler::CompilerType<HGL::Vector2D> {
    DISALLOW_COPY_AND_ASSIGN(Vector2D)
public:
    Vector2D(float x, float y, int line);

    using IType::operator=;

    virtual operator HGL::Vector2D &() const throw(InvalidExpressionException);
protected:
    virtual ~Vector2D();

    void append(ISerializeable::BUFFER *dest, const HGL::IType *type) const;
};

}

}

这里是模板:

#include "compilerbase.h"
#include "iproject.h"
#include "util.h"

namespace HGL {

namespace Compiler {

const IProject::VSTRUCT minReq = { HGL_MINREQ_MAJOR, HGL_MINREQ_MAJOR, HGL_MINREQ_MAJOR };

template<class Type, class Base = CompilerBase>
class _LOCAL CompilerType : public Type, public Base {
    DISALLOW_COPY_AND_ASSIGN(CompilerType)
public:
    using IType::operator=;

    template<class Param>
    inline CompilerType(const Param &p, bool b, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) :
        Type(p), Base(line, b) {
        init(vs);
    }

    template<class Param>
    inline CompilerType(const Param &p, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(p), Base(line) {
        init(vs);
    }

    inline CompilerType(bool b, int line, const IProject::VSTRUCT &vs = IProject::VSTRUCT())
        : Type(), Base(line, b) {
        init(vs);
    }

    template<class Param1, class Param2>
    inline CompilerType(const Param1 &p1, const Param2 &p2, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) :
        Type(p1, p2), Base(line) {
        init(vs);
    }

    template<class Param1, class Param2>
    inline CompilerType(const Param1 &p1, const Param2 &p2, bool b, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(p1, p2),
        Base(line, b) {
        init(vs);
    }

    inline CompilerType(int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(), Base(line) {
        init(vs);
    }

    inline virtual void append(ISerializeable::BUFFER *dest, const IType *type) const {
        Base::append(dest, type);
    }

protected:
    inline virtual ~CompilerType() {}

    inline virtual void init(const IProject::VSTRUCT &vs) {
        const_cast<IProject::VSTRUCT &>(vs) = std::max(vs, minReq);
        CompilerBase::setMinRequiredVersion(vs, Type::getSerialID());
    }

};

}

}

解决!

在深入研究g ++ 4.2的源代码之后,我发现它现在需要完整树中的所有类型。 g ++&gt; 4.2显然不需要这个。

因此,错误发生在一个相关的类中,该类具有转发特化的模板成员。我只是包含了标题而不是转发,g ++ 4.2很高兴。

否则,这是一个非常好的错误,不会给出错误,但是这个无用的消息。

1 个答案:

答案 0 :(得分:1)

thunk trampoline 是在动态调度的某些实现中添加的一段代码,用于调整基本虚函数的接口以适应最终的覆盖正在使用。正如您所提到的,通常需要在多个/虚拟继承中调整this指针(对于在第一个非空对象之后列出的基数),并使用协变返回类型调整结果指针/引用。

错误表明它是编译器错误。如果必须使用该特定编译器,则需要解决该问题,这将涉及更改您的设计。您可以尝试限制多个/虚拟继承的使用,重新排序列表中的基数或尝试使用,直到您设法让编译器以某种方式消化该代码。如果在为协变返回类型生成适配器时出现问题,请考虑删除协变返回并提供将返回协变类型的重载(即使用非虚函数替换协变返回)派生类型和调用前一个的虚函数,并返回对基数的引用。)

除了那些通用提示之外,如果没有看到你拥有的代码和编译器的实现,那么除此之外别无他法。