[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-05-03 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #8 from Jonathan Wakely  ---
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).

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-05-02 Thread Daniel.Withopf at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #7 from Daniel  ---
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?

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-04-30 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #6 from Jonathan Wakely  ---
(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().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

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-04-29 Thread Daniel.Withopf at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #5 from Daniel  ---
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?

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-04-29 Thread webrown.cpp at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #4 from W E Brown  ---
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.

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-04-29 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #3 from Jonathan Wakely  ---
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).

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-04-29 Thread Daniel.Withopf at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #2 from Daniel  ---
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.

[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object

2021-04-29 Thread webrown.cpp at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

W E Brown  changed:

   What|Removed |Added

 CC||webrown.cpp at gmail dot com

--- Comment #1 from W E Brown  ---
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.