Skip to content

Linking problems with multiple translation units #37

@bitbugprime

Description

@bitbugprime

The internal function contract_violation() shares the same function signature between two different versions, depending on whether TCB_SPAN_THROW_ON_CONTRACT_VIOLATION is defined.

This is no problem until multiple translation units are linked together and TCB_SPAN_THROW_ON_CONTRACT_VIOLATION is defined in some but not all of them. The linker chooses one of the definitions and throws away the other, which means that the translation units that turned on TCB_SPAN_THROW_ON_CONTRACT_VIOLATION can end up erroneously calling the std::terminate version if that is the one the linker chose. Or vice-versa I presume. I see this in debug builds using GCC 8 or 10.

You can fix this problem by giving the throwing version a different function signature. For example:
inline void contract_violation(const char* msg, int = 0)

It also seems to me that the throwing version should be [[noreturn]] like the std::terminate version, since it too never returns and [[noreturn]] because of throw was explicitly contemplated in many [[noreturn]] examples I've seen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions