https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117317
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Slightly cleaned up: struct C { constexpr bool operator== (const C &b) const { return foo (); } constexpr virtual bool foo () const = 0; }; class A : public C {}; class B : public C {}; template <int> struct D : A, B { constexpr bool operator== (const D &) const = default; constexpr bool foo () const override { return true; } }; struct E : D<1> {}; constexpr E e; constexpr E f; static_assert (e == f, ""); Seems we call expand_or_defer_fn on the D<1>::foo, and given that it is constexpr and thus inline, we just call tentative_decl_linkage on it until we figure out if we really need to emit it or not. But expand_or_defer_fn calls emit_associated_thunks, which calls use_thunk and that asserts DECL_INTERFACE_KNOWN, which is not the case for the tentative linkage decls.