public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden
@ 2024-08-26 22:17 mail at johslarsen dot net
2024-08-26 22:30 ` [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass pinskia at gcc dot gnu.org
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: mail at johslarsen dot net @ 2024-08-26 22:17 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
Bug ID: 116492
Summary: inherited constructors in subclass of std::expected
can not be overridden
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: mail at johslarsen dot net
Target Milestone: ---
Created attachment 59007
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59007&action=edit
preprocessed file
First of all, sorry I subclassed the standard library, and yes, I am perfectly
aware that this is a very bad practice. As such the important part might not be
a fix for this in particular, but that it could shed light on similar problems
elsewhere
The following code snippet compiled with gcc 12.1 (first with std::expected on
godbolt) through 14.2 (and trunk) constructs obj by calling std::expected's
constructor directly instead of the constructor defined in my_expected:
#include <expected>
class my_expected : public std::expected<int, const char*> {
public:
my_expected() : std::expected<int, const char*>::expected(42) {}
using std::expected<int, const char*>::expected;
};
int main() {
my_expected obj;
return *obj != 42;
}
Resulting in *obj being zero (instead of 42), and a non-zero exit value.
This only happens with the using statement, but as far as I understand the C++
documentation the derived constructor should have been used instead:
> [...] if an inherited constructor matches the signature of one of the constructors
> of Derived, it is hidden from lookup by the version found in Derived.
> https://en.cppreference.com/w/cpp/language/using_declaration
The same does not happen in clang, and in gcc with similar examples from other
classes I have tried. g++ returns no errors or warnings with -Wall -Wextra and
all the other flags you suggested. The attached preprocessed file was generated
with g++ 14.2.1 20240805
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
@ 2024-08-26 22:30 ` pinskia at gcc dot gnu.org
2024-08-26 22:33 ` pinskia at gcc dot gnu.org
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-08-26 22:30 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed| |2024-08-26
Summary|inherited constructors in |inherited constructors with
|subclass of std::expected |concept in subclass
|can not be overridden |overrides constructor in
| |subclass
Blocks| |67491
Status|UNCONFIRMED |NEW
Keywords| |wrong-code
Ever confirmed|0 |1
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Slightly reduced:
```
template <class T>
concept true_c = true;
template <class T>
struct expected
{
T a;
bool hasvalue;
constexpr expected(T a1) : a(a1), hasvalue(true){}
constexpr expected()
requires true_c<T>
: a(), hasvalue(true){}
expected(expected&&) = default;
T &operator*()
{
if (!hasvalue) throw 1;
return a;
}
};
class my_expected : public expected<int> {
public:
using expected<int>::expected;
my_expected() : expected<int>::expected(42) {}
};
int main() {
my_expected obj;
return *obj != 42;
}
```
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
[Bug 67491] [meta-bug] concepts issues
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
2024-08-26 22:30 ` [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass pinskia at gcc dot gnu.org
@ 2024-08-26 22:33 ` pinskia at gcc dot gnu.org
2024-08-26 22:35 ` pinskia at gcc dot gnu.org
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-08-26 22:33 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>The same does not happen in clang, and in gcc with similar examples from other classes I have tried.
So it comes down to the concept on the constructor which is why you didn't run
into similar examples from other classes. std::expected has requires
statements on the constructors in some cases.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
2024-08-26 22:30 ` [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass pinskia at gcc dot gnu.org
2024-08-26 22:33 ` pinskia at gcc dot gnu.org
@ 2024-08-26 22:35 ` pinskia at gcc dot gnu.org
2024-09-04 18:45 ` ppalka at gcc dot gnu.org
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-08-26 22:35 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> Slightly reduced:
In this example if you comment out:
```
requires true_c<T>
```
GCC does the correct thing.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
` (2 preceding siblings ...)
2024-08-26 22:35 ` pinskia at gcc dot gnu.org
@ 2024-09-04 18:45 ` ppalka at gcc dot gnu.org
2024-09-17 15:17 ` ppalka at gcc dot gnu.org
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: ppalka at gcc dot gnu.org @ 2024-09-04 18:45 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
Patrick Palka <ppalka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jason at gcc dot gnu.org,
| |ppalka at gcc dot gnu.org
Alias| |cwg2789
--- Comment #4 from Patrick Palka <ppalka at gcc dot gnu.org> ---
More reduced:
template<class T>
struct A {
A() requires true = delete; // #1
};
struct B : A<int> {
using A<int>::A;
B(); // #2
};
B b; // GCC and Clang-17 select #1, MSVC/Clang-18 select #2
This seems to be a recent behavior change in the standard,
https://wg21.link/cwg2789, which GCC doesn't fully implement, in particular the
...
if they are member functions, both are direct members of the same class, and
...
part.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
` (3 preceding siblings ...)
2024-09-04 18:45 ` ppalka at gcc dot gnu.org
@ 2024-09-17 15:17 ` ppalka at gcc dot gnu.org
2024-09-20 16:34 ` cvs-commit at gcc dot gnu.org
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: ppalka at gcc dot gnu.org @ 2024-09-17 15:17 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
Patrick Palka <ppalka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
See Also| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=113191
--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
I tried implementing the missing inherited vs non-inherited check from CWG2789
in cand_parms_match which fixes this testcase but it causes concepts-memfun4.C
(added by r14-7157) to regress with excess errors. The new errors/behavior
seem correct to me, so I must be missing something...
Before/after diff of concepts-memfun4.C:
@@ -1,3 +1,34 @@
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:26:25: error: static assertion
failed
+ 26 | static_assert(S<>{}.f() == 5);
+ | ~~~~~~~~~~^~~~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:26:25: note: the comparison
reduces to ‘(10 == 5)’
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:27:22: error: call of overloaded
‘g()’ is ambiguous
+ 27 | static_assert(S<>{}.g() == 5);
+ | ~~~~~~~^~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:10:17: note: candidate:
‘constexpr int B<T>::g(this S<T>&&) requires true [with T = void]’
+ 10 | constexpr int g(this S<T>&&) requires true { return 5; }
+ | ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:21:17: note: candidate:
‘constexpr int S< <template-parameter-1-1> >::g() [with
<template-parameter-1-1> = void]’
+ 21 | constexpr int g() { return 10; }
+ | ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:28:22: error: call of overloaded
‘h()’ is ambiguous
+ 28 | static_assert(S<>{}.h() == 5);
+ | ~~~~~~~^~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:11:17: note: candidate:
‘constexpr int B<T>::h() requires true [with T = void]’
+ 11 | constexpr int h() requires true { return 5; }
+ | ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:22:17: note: candidate:
‘constexpr int S< <template-parameter-1-1> >::h(this S<
<template-parameter-1-1> >&&) [with <template-parameter-1-1> = void]’
+ 22 | constexpr int h(this S&&) { return 10; }
+ | ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:41:15: error: conversion from
‘S2<>’ to ‘int’ is ambiguous
+ 41 | static_assert(S2<>{} == 5);
+ | ^~~~~~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:33:13: note: candidate:
‘constexpr C< <template-parameter-1-1> >::operator int() const [with
<template-parameter-1-1> = void]’
+ 33 | constexpr operator int () const { return 15; }
+ | ^~~~~~~~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:9:13: note: candidate:
‘constexpr B<T>::operator int() const requires true [with T = void]’
+ 9 | constexpr operator int () const requires true { return 5; }
+ | ^~~~~~~~
gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:46:22: error: request for member
‘f’ is ambiguous
46 | static_assert(S2<>{}.f() == 5); // { dg-error "ambiguous" }
| ^
@@ -16,6 +47,19 @@ gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:8:17: note:
candidate: ‘constexp
gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:51:17: note: candidate:
‘constexpr int S3< <template-parameter-1-1> >::f() volatile [with
<template-parameter-1-1> = void]’
51 | constexpr int f() volatile { return 10; }
| ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:64:23: warning: ISO C++ says
that these are ambiguous, even though the worst conversion for the first is
better than the worst conversion for the second:
+ 64 | static_assert(S4<>{}.f() == 5);
+ | ~~~~~~~~^~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:60:17: note: candidate 1:
‘constexpr int S4< <template-parameter-1-1> >::f() const & [with
<template-parameter-1-1> = void]’
+ 60 | constexpr int f() const & { return 10; }
+ | ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:8:17: note: candidate 2:
‘constexpr int B<T>::f() const requires true [with T = void]’
+ 8 | constexpr int f() const requires true { return 5; }
+ | ^
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:64:26: error: static assertion
failed
+ 64 | static_assert(S4<>{}.f() == 5);
+ | ~~~~~~~~~~~^~~~
+gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:64:26: note: the comparison
reduces to ‘(10 == 5)’
gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C:75:15: error: conversion from
‘S5<>’ to ‘int’ is ambiguous
75 | static_assert(S5<>{} == 5); // { dg-error "ambiguous" }
| ^~~~~~
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
` (4 preceding siblings ...)
2024-09-17 15:17 ` ppalka at gcc dot gnu.org
@ 2024-09-20 16:34 ` cvs-commit at gcc dot gnu.org
2024-09-20 21:37 ` cvs-commit at gcc dot gnu.org
2024-09-20 21:38 ` ppalka at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-09-20 16:34 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>:
https://gcc.gnu.org/g:ee3efe06c9c49c04eaa4e195a7ae8774a1b3faa2
commit r15-3741-gee3efe06c9c49c04eaa4e195a7ae8774a1b3faa2
Author: Patrick Palka <ppalka@redhat.com>
Date: Fri Sep 20 12:33:13 2024 -0400
c++: CWG 2789 and usings [PR116492]
After CWG 2789, the "more constrained" tiebreaker for non-template
functions should exclude member functions that are defined in
different classes. This patch implements this missing refinement.
In turn we can get rid of four-parameter version of object_parms_correspond
and call the main overload directly since now correspondence is only
only checked for members from the same class.
PR c++/116492
DR 2789
gcc/cp/ChangeLog:
* call.cc (object_parms_correspond): Remove.
(cand_parms_match): Return false for member functions that come
from different classes. Adjust call to object_parms_correspond.
(joust): Update comment for the non-template "more constrained"
case.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-memfun4.C: Also compile in C++20 mode.
Expect ambiguity when candidates come from different classes.
* g++.dg/cpp2a/concepts-inherit-ctor12.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
` (5 preceding siblings ...)
2024-09-20 16:34 ` cvs-commit at gcc dot gnu.org
@ 2024-09-20 21:37 ` cvs-commit at gcc dot gnu.org
2024-09-20 21:38 ` ppalka at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-09-20 21:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-14 branch has been updated by Patrick Palka
<ppalka@gcc.gnu.org>:
https://gcc.gnu.org/g:659f32ea9de57661f8a37dcfb0b9a01bfe29acce
commit r14-10696-g659f32ea9de57661f8a37dcfb0b9a01bfe29acce
Author: Patrick Palka <ppalka@redhat.com>
Date: Fri Sep 20 17:37:03 2024 -0400
c++: CWG 2789 and usings [PR116492]
For GCC 14, narrowly fix this PR by implementing the missing
- if they are member functions, both are direct members of the same
class, and
part of CWG 2789 for constructors only.
PR c++/116492
DR 2789
gcc/cp/ChangeLog:
* call.cc (cand_parms_match): Return false for constructors that
come from different classes.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-inherit-ctor12.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
` (6 preceding siblings ...)
2024-09-20 21:37 ` cvs-commit at gcc dot gnu.org
@ 2024-09-20 21:38 ` ppalka at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: ppalka at gcc dot gnu.org @ 2024-09-20 21:38 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
Patrick Palka <ppalka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |14.3
Resolution|--- |FIXED
Status|NEW |RESOLVED
Assignee|unassigned at gcc dot gnu.org |ppalka at gcc dot gnu.org
--- Comment #8 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Narrowly fixed for GCC 14.3, fully fixed GCC 15, thanks for the bug report.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-09-20 21:38 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-26 22:17 [Bug c++/116492] New: inherited constructors in subclass of std::expected can not be overridden mail at johslarsen dot net
2024-08-26 22:30 ` [Bug c++/116492] inherited constructors with concept in subclass overrides constructor in subclass pinskia at gcc dot gnu.org
2024-08-26 22:33 ` pinskia at gcc dot gnu.org
2024-08-26 22:35 ` pinskia at gcc dot gnu.org
2024-09-04 18:45 ` ppalka at gcc dot gnu.org
2024-09-17 15:17 ` ppalka at gcc dot gnu.org
2024-09-20 16:34 ` cvs-commit at gcc dot gnu.org
2024-09-20 21:37 ` cvs-commit at gcc dot gnu.org
2024-09-20 21:38 ` ppalka 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).