Upgrade: address warnings -- shaddowing overloaded-virtual
This is an advanced diagnostics added (presumably) with GCC-13 and attempts to protect against an insidious side-effect of ''overload resolution'' Basically C++ (like its ancestor C) is oriented towards direct linkage and adds the OO-style dynamic dispatch (through virtual functions and a VTable) only as an extension, which must be requested explicitly. Thus the resolution of ''overloads'' (as opposed to ''overridden'' virtual functions) always takes precedence and happens within the directly visible scope, which can cause the compiler to perform an implicit conversion instead of invoking a different virtual function, which is defined in a base class. However, this diagnostics seems to be implemented in an overly zealous way: The compiler warns at the time of the type instantiation, and even in cases where it is effectively impossible to encounter this dangerous shadowing situation. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740 This leads to several ill-guided warnings in the Lumiera code base, which unfortunately can only be addressed by disabling this diagnostics for all usages of some header. The reason is, we often generate chains of template instantiations driven by type lists, and in such usage pattern, it is not even possible to bring all the other inherited overloads into scope (with a using `BASE::func` clause), because such a specification would be ambiguous and result in a real compile error, because even the interface is generated from a chain of mix-in templates
This commit is contained in:
parent
bf6532a69d
commit
47f5390b18
4 changed files with 40 additions and 5 deletions
|
|
@ -57,6 +57,13 @@
|
||||||
#include "lib/meta/trait.hpp"
|
#include "lib/meta/trait.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
// GCC > 13 warns at class definition when a new overload shadows an inherited virtual function.
|
||||||
|
// While theoretically correct, in practice any call will be dispatched through the base interface,
|
||||||
|
// which in turn is also generated by metaprogramming from a type list.
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"")
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace meta {
|
namespace meta {
|
||||||
|
|
@ -159,7 +166,7 @@ namespace meta {
|
||||||
return accessTargetElement();
|
return accessTargetElement();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}//(End)implementation details
|
}//(End)implementation details
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ namespace meta{
|
||||||
class NoCopyMoveSupport
|
class NoCopyMoveSupport
|
||||||
: public B
|
: public B
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
virtual void
|
virtual void
|
||||||
copyInto (void*) const override
|
copyInto (void*) const override
|
||||||
{
|
{
|
||||||
|
|
@ -178,6 +179,7 @@ namespace meta{
|
||||||
class MoveSupport
|
class MoveSupport
|
||||||
: public NoCopyMoveSupport<I,D,B>
|
: public NoCopyMoveSupport<I,D,B>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
virtual void
|
virtual void
|
||||||
copyInto (void*) const override
|
copyInto (void*) const override
|
||||||
{
|
{
|
||||||
|
|
@ -190,6 +192,10 @@ namespace meta{
|
||||||
D& src = static_cast<D&> (*this);
|
D& src = static_cast<D&> (*this);
|
||||||
new(targetStorage) D(move(src));
|
new(targetStorage) D(move(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// irrelevant for any practical usage, but formally required
|
||||||
|
using NoCopyMoveSupport<I,D,B>::copyInto;
|
||||||
|
using NoCopyMoveSupport<I,D,B>::moveInto;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -197,12 +203,15 @@ namespace meta{
|
||||||
class CloneSupport
|
class CloneSupport
|
||||||
: public MoveSupport<I,D,B>
|
: public MoveSupport<I,D,B>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
virtual void
|
virtual void
|
||||||
copyInto (void* targetStorage) const override
|
copyInto (void* targetStorage) const override
|
||||||
{
|
{
|
||||||
D const& src = static_cast<D const&> (*this);
|
D const& src = static_cast<D const&> (*this);
|
||||||
new(targetStorage) D(src);
|
new(targetStorage) D(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using MoveSupport<I,D,B>::copyInto;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -210,6 +219,7 @@ namespace meta{
|
||||||
class FullCopySupport
|
class FullCopySupport
|
||||||
: public CloneSupport<I,D,B>
|
: public CloneSupport<I,D,B>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
virtual void
|
virtual void
|
||||||
copyInto (I& target) const override
|
copyInto (I& target) const override
|
||||||
{
|
{
|
||||||
|
|
@ -225,8 +235,12 @@ namespace meta{
|
||||||
D& s = static_cast<D&> (*this);
|
D& s = static_cast<D&> (*this);
|
||||||
t = move(s);
|
t = move(s);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
using CloneSupport<I,D,B>::copyInto;
|
||||||
|
using CloneSupport<I,D,B>::moveInto;
|
||||||
|
}; // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
|
||||||
|
// In our case here, calls will always be through VirtualCopySupportInterface
|
||||||
|
// and void* is incompatible with I&, so the warning is irrelevant...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,15 @@ namespace session {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// GCC > 13 warns at class definition when a new overload shadows an inherited virtual function.
|
||||||
|
// While theoretically correct, in practice any call will be dispatched through the base interface
|
||||||
|
// and it is not even possible to reach the concrete classes (and the implementation function is private).
|
||||||
|
// The workaround with a `using` clause is not applicable, since the name is ambiguous (by design)
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"")
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* building block providing the
|
* building block providing the
|
||||||
* mock implementation for a \em single type.
|
* mock implementation for a \em single type.
|
||||||
|
|
@ -167,7 +176,6 @@ namespace session {
|
||||||
{
|
{
|
||||||
typedef typename WrapReturn<TY>::Wrapper Ret;
|
typedef typename WrapReturn<TY>::Wrapper Ret;
|
||||||
|
|
||||||
|
|
||||||
/** (dummy) implementation of the QueryHandler interface */
|
/** (dummy) implementation of the QueryHandler interface */
|
||||||
virtual bool
|
virtual bool
|
||||||
resolve (Ret& solution, Query<TY> const& q)
|
resolve (Ret& solution, Query<TY> const& q)
|
||||||
|
|
@ -184,7 +192,6 @@ namespace session {
|
||||||
return try_special_case(solution, q);
|
return try_special_case(solution, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
bool
|
bool
|
||||||
try_special_case (Ret& solution, Query<TY> const& q)
|
try_special_case (Ret& solution, Query<TY> const& q)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@ using util::_Fmt;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
|
||||||
|
// GCC > 13 warns at class definition when a new overload shadows an inherited virtual function.
|
||||||
|
// While theoretically correct, this warning is besides the point when an interface is assembled
|
||||||
|
// by metaprogramming from a chain of template instantiations, driven by a type list
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"")
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace meta {
|
namespace meta {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue