public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/100335] New: Using statement of a ref-qualified method from base class: method not callable on derived object
@ 2021-04-29 14:48 Daniel.Withopf at web dot de
  2021-04-29 21:01 ` [Bug c++/100335] " webrown.cpp at gmail dot com
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Daniel.Withopf at web dot de @ 2021-04-29 14:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

            Bug ID: 100335
           Summary: Using statement of a ref-qualified method from base
                    class: method not callable on derived object
           Product: gcc
           Version: 10.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Daniel.Withopf at web dot de
  Target Milestone: ---

The following code examples defines 2 ref-qualified method with identical names
in a base class (const& and const&&). Derived also defines a (non-const) method
with the same name and adds a "using Base::method;"

With all gcc Versions I tested (10.3, 9.3, 8.3, 7.5), the compilation with
--std=c++11 or --std=c++14 fails if the method in the derived class does not
have a ref-qualifier.

class Base {
public:
  void method() const&& {}
  void method() const& {}
};

class Derived : public Base {
public:
  using Base::method;
  // this leads to a compiler error
  void method() {}

  // with a ref-qualifier the code is compiling
  //  void method() & {}
};

int main() {
    const Derived test;
    test.method();
}

I believe that this is incorrect and the code should also compile when the
method in the Derived class has no ref-qualifier.

^ 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 ` 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

end of thread, other threads:[~2021-05-03 14:15 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).