* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
@ 2021-04-29 21:01 ` webrown.cpp at gmail dot com
2021-04-29 21:47 ` Daniel.Withopf at web dot de
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: webrown.cpp at gmail dot com @ 2021-04-29 21:01 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
W E Brown <webrown.cpp at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |webrown.cpp at gmail dot com
--- Comment #1 from W E Brown <webrown.cpp at gmail dot com> ---
According to C++20 [over.load]/2.3:
"Member function declarations ... cannot be overloaded if any of them, but not
all, have a ref-qualifier...."
Therefore, the above example's Base class compiles because each of its
overloaded member functions has a ref-qualifier. However, Derived::method is
not ref-qualified, so treating it as an overload of those Base functions would
violate the above-cited passage.
Accordingly, unless I've overlooked some exception to this rule, I respectfully
suggest this issue be closed as invalid.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
2021-04-29 21:01 ` [Bug c++/100335] " webrown.cpp at gmail dot com
@ 2021-04-29 21:47 ` Daniel.Withopf at web dot de
2021-04-29 21:53 ` redi at gcc dot gnu.org
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Daniel.Withopf at web dot de @ 2021-04-29 21:47 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #2 from Daniel <Daniel.Withopf at web dot de> ---
As an extra Info: the other compilers I tested (e.g. clang) accept the code
example as is.
But after reading the cited pet of the standard It seems that GCC is right in
rejecting this and the other compilers have an issue.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
2021-04-29 21:01 ` [Bug c++/100335] " webrown.cpp at gmail dot com
2021-04-29 21:47 ` Daniel.Withopf at web dot de
@ 2021-04-29 21:53 ` redi at gcc dot gnu.org
2021-04-30 1:18 ` webrown.cpp at gmail dot com
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-04-29 21:53 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I don't know if that rule applies here. If it did, this would be invalid too
(by [over.load]/2.1), but all compilers agree that this is OK:
struct Base {
int method() {}
};
struct Derived : Base {
using Base::method;
void method() {}
};
I believe the relevant rule for my example is [namespace.udecl[/14 which says
that declarations from a base class are hidden by declarations in the derived
class with the same name, parameter clause and ref-qualifier (if any), and that
hidden names are excluded from the set introduced by the using-declaration.
Which means that Base::method() is hidden by Derived::method() and so not
introduced.
It looks like GCC is applying that same rule for the original example, so that
Derived::method() hides the Base::method() const& and Base::method const&&
declarations that would otherwise conflict. That means the only overload
candidate for test.method() is Derived::method() which can't be called on a
const object. However, [namespace.udecl]/14 seems clear that such hiding should
only happen if the ref-qualifers are the same.
Other compilers (Clang, EDG and MSVC) accept the original example, which I
can't explain. Either the overloads should conflict because of [over.load]/2.3
(and the definition of Derived should be ill-formed) or they should be hidden
and not visible in Derived (so the call to test.method() should be ill-formed).
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
` (2 preceding siblings ...)
2021-04-29 21:53 ` redi at gcc dot gnu.org
@ 2021-04-30 1:18 ` webrown.cpp at gmail dot com
2021-04-30 6:45 ` Daniel.Withopf at web dot de
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: webrown.cpp at gmail dot com @ 2021-04-30 1:18 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #4 from W E Brown <webrown.cpp at gmail dot com> ---
I won't comment on any compiler's behavior, but do want to thank you for
reminding me of [namespace.udecl]/14:
"When a using-declarator brings declarations from a base class into a derived
class, member functions ... in the derived class override and/or hide member
functions .. with the same name, parameter-type-list ..., and ref-qualifier (if
any), in a base class...."
Upon reflection, I believe that [namespace.udecl]/14 does not apply to the
original example because the ref-qualifier on Derived::method (i.e., none) is
not "the same" as the ref-qualifier on either Base::method. Thus, there's no
overriding and/or hiding to be done there.
However, I believe that [namespace.udecl]/14 *does* apply to the example in
Comment 3, where Base::method and Derived::method do have "the same"
ref-qualifier (i.e., none). There, Derived::method ought to hide Base::method
as [over.load]/2.3 seems be inapplicable.
In brief, I believe Comment 3's example ought compile due to
[namespace.udecl]/14, but the original example ought not compile due to
[over.load]/2.3.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
` (3 preceding siblings ...)
2021-04-30 1:18 ` webrown.cpp at gmail dot com
@ 2021-04-30 6:45 ` Daniel.Withopf at web dot de
2021-04-30 10:29 ` redi at gcc dot gnu.org
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Daniel.Withopf at web dot de @ 2021-04-30 6:45 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #5 from Daniel <Daniel.Withopf at web dot de> ---
As a sidenote, the original example is also compiling if test object is made
non-const, i.e. "const Derived test;" is replaced with "Derived test;"
If the argument in Comment 1 is true than the program would still be ill-formed
in this case, wouldn't it?
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
` (4 preceding siblings ...)
2021-04-30 6:45 ` Daniel.Withopf at web dot de
@ 2021-04-30 10:29 ` redi at gcc dot gnu.org
2021-05-03 6:38 ` Daniel.Withopf at web dot de
2021-05-03 14:15 ` redi at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-04-30 10:29 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to W E Brown from comment #4)
> In brief, I believe Comment 3's example ought compile due to
> [namespace.udecl]/14, but the original example ought not compile due to
> [over.load]/2.3.
But [over.load]/2.3 is not why GCC gives an error. The definition of Derived is
accepted, it's trying to call declval<const Derived&>().method() that is
rejected.
None of GCC, Clang, EDG or MSVC reject the definition of Derived.
(In reply to Daniel from comment #5)
> As a sidenote, the original example is also compiling if test object is made
> non-const, i.e. "const Derived test;" is replaced with "Derived test;"
>
> If the argument in Comment 1 is true than the program would still be
> ill-formed in this case, wouldn't it?
Yes.
I'm not sure what the relevant rule is here, but I don't think it's
[over.load]/2.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
` (5 preceding siblings ...)
2021-04-30 10:29 ` redi at gcc dot gnu.org
@ 2021-05-03 6:38 ` Daniel.Withopf at web dot de
2021-05-03 14:15 ` redi at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: Daniel.Withopf at web dot de @ 2021-05-03 6:38 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #7 from Daniel <Daniel.Withopf at web dot de> ---
To me it seems that [over.load] is the right section of the standard as the
start of the section explicitly mentions that the rules there (either all or
none of the overloads must have ref-qualifiers) applies when a using
declaration is involved:
"Not all function declarations can be overloaded. Those that cannot be
overloaded are specified here. A program is ill-formed if it contains two such
non-overloadable declarations in the same scope. [Note:This restriction applies
to explicit declarations in a scope, and between such declarations and
declarations made through a using-declaration(7.3.3). It does not apply to sets
of functions fabricated as a result of name lookup (e.g., because of
using-directives) or overload resolution (e.g., for operator functions).— end
note]"
Could it be that
- gcc is on the right track by rejecting the example, but it should also reject
the code in the case where the offending method is not called (see Comment 6)?
- clang, MSVC are not taking the above note into consideration and thus are
missing an error in this case?
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
2021-04-29 14:48 [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object Daniel.Withopf at web dot de
` (6 preceding siblings ...)
2021-05-03 6:38 ` Daniel.Withopf at web dot de
@ 2021-05-03 14:15 ` redi at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-05-03 14:15 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335
--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Like I already suggested in comment 3:
Either the overloads should conflict because of [over.load]/2.3 (and the
definition of Derived should be ill-formed) or they should be hidden and not
visible in Derived (so the call to test.method() should be ill-formed).
^ permalink raw reply [flat|nested] 9+ messages in thread