[1/2] c++: CWG 2273 and non-constructors
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
Commit Message
Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
incorrectly considering all inherited members, not just inherited
constructors. This patch restricts the tiebreaker accordingly.
DR 2273
gcc/cp/ChangeLog:
* call.cc (joust): Restrict inheritedness tiebreaker to
constructors.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
* g++.dg/overload/using5.C: Likewise.
---
gcc/cp/call.cc | 12 +++++-------
gcc/testsuite/g++.dg/cpp1z/using1.C | 7 +++----
gcc/testsuite/g++.dg/overload/using5.C | 2 +-
3 files changed, 9 insertions(+), 12 deletions(-)
Comments
On Wed, 18 Sep 2024, Patrick Palka wrote:
> Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
> incorrectly considering all inherited members, not just inherited
> constructors. This patch restricts the tiebreaker accordingly.
>
> DR 2273
>
> gcc/cp/ChangeLog:
>
> * call.cc (joust): Restrict inheritedness tiebreaker to
> constructors.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
> * g++.dg/overload/using5.C: Likewise.
> ---
> gcc/cp/call.cc | 12 +++++-------
> gcc/testsuite/g++.dg/cpp1z/using1.C | 7 +++----
> gcc/testsuite/g++.dg/overload/using5.C | 2 +-
> 3 files changed, 9 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> index 3f753e2d2f9..87b54291b51 100644
> --- a/gcc/cp/call.cc
> +++ b/gcc/cp/call.cc
> @@ -13350,13 +13350,11 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
> }
> }
>
> - /* F1 is a member of a class D, F2 is a member of a base class B of D, and
> - for all arguments the corresponding parameters of F1 and F2 have the same
> - type (CWG 2273/2277). */
> - if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
> - && !DECL_CONV_FN_P (cand1->fn)
> - && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
> - && !DECL_CONV_FN_P (cand2->fn))
> + /* F1 is a constructor for a class D, F2 is a constructor for a base class B
> + of D, and for all arguments the corresponding parameters of F1 and F2 have
> + the same type (CWG 2273/2277). */
> + if (DECL_P (cand1->fn) && DECL_CONSTRUCTOR_P (cand1->fn)
> + && DECL_P (cand2->fn) && DECL_CONSTRUCTOR_P (cand2->fn))
Here's v2 which refines this condition to check DECL_INHERITED_CTOR
instead. No functional change, but this more narrow condition seems
cleaner.
-- >8 --
Subject: [PATCH 1/2] c++: CWG 2273 and non-constructors
Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
incorrectly considering all member functions introduced via using, not
just constructors. This patch restricts the tiebreaker accordingly.
DR 2273
gcc/cp/ChangeLog:
* call.cc (joust): Restrict inheritedness tiebreaker to
constructors.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
* g++.dg/overload/using5.C: Likewise.
---
gcc/cp/call.cc | 11 ++++-------
gcc/testsuite/g++.dg/cpp1z/using1.C | 8 ++++----
gcc/testsuite/g++.dg/overload/using5.C | 2 +-
3 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 3f753e2d2f9..6229dc45263 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13350,13 +13350,10 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
}
}
- /* F1 is a member of a class D, F2 is a member of a base class B of D, and
- for all arguments the corresponding parameters of F1 and F2 have the same
- type (CWG 2273/2277). */
- if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
- && !DECL_CONV_FN_P (cand1->fn)
- && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
- && !DECL_CONV_FN_P (cand2->fn))
+ /* F1 is a constructor for a class D, F2 is a constructor for a base class B
+ of D, and for all arguments the corresponding parameters of F1 and F2 have
+ the same type (CWG 2273/2277). */
+ if (DECL_INHERITED_CTOR (cand1->fn) || DECL_INHERITED_CTOR (cand2->fn))
{
tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
diff --git a/gcc/testsuite/g++.dg/cpp1z/using1.C b/gcc/testsuite/g++.dg/cpp1z/using1.C
index 1ed939d45fd..d8a04525579 100644
--- a/gcc/testsuite/g++.dg/cpp1z/using1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/using1.C
@@ -1,5 +1,5 @@
-// Test for hiding of used base functions when all the conversion sequences are
-// equivalent, needed to avoid a regression on inherited default ctors.
+// Test the CWG 2273 inheritedness tiebreaker doesn't apply to
+// non-constructors.
struct A
{
@@ -17,7 +17,7 @@ struct B:A
int main()
{
- B().f(1); // OK, derived f hides base f for single arg
+ B().f(1); // { dg-error "ambiguous" }
B().f(1,2); // OK, base f can still be called with two args
- B().g(1); // { dg-error "" } signatures differ, ambiguous
+ B().g(1); // { dg-error "ambiguous" }
}
diff --git a/gcc/testsuite/g++.dg/overload/using5.C b/gcc/testsuite/g++.dg/overload/using5.C
index ad17c78a561..0933a9f0fac 100644
--- a/gcc/testsuite/g++.dg/overload/using5.C
+++ b/gcc/testsuite/g++.dg/overload/using5.C
@@ -24,5 +24,5 @@ struct C: B {
int main()
{
C c (42);
- c.f();
+ c.f(); // { dg-error "ambiguous" }
}
On 9/20/24 4:02 PM, Patrick Palka wrote:
> On Wed, 18 Sep 2024, Patrick Palka wrote:
>
>> Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
>> incorrectly considering all inherited members, not just inherited
>> constructors. This patch restricts the tiebreaker accordingly.
>>
>> DR 2273
>>
>> gcc/cp/ChangeLog:
>>
>> * call.cc (joust): Restrict inheritedness tiebreaker to
>> constructors.
>>
>> gcc/testsuite/ChangeLog:
>>
>> * g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
>> * g++.dg/overload/using5.C: Likewise.
>> ---
>> gcc/cp/call.cc | 12 +++++-------
>> gcc/testsuite/g++.dg/cpp1z/using1.C | 7 +++----
>> gcc/testsuite/g++.dg/overload/using5.C | 2 +-
>> 3 files changed, 9 insertions(+), 12 deletions(-)
>>
>> diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
>> index 3f753e2d2f9..87b54291b51 100644
>> --- a/gcc/cp/call.cc
>> +++ b/gcc/cp/call.cc
>> @@ -13350,13 +13350,11 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
>> }
>> }
>>
>> - /* F1 is a member of a class D, F2 is a member of a base class B of D, and
>> - for all arguments the corresponding parameters of F1 and F2 have the same
>> - type (CWG 2273/2277). */
>> - if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
>> - && !DECL_CONV_FN_P (cand1->fn)
>> - && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
>> - && !DECL_CONV_FN_P (cand2->fn))
>> + /* F1 is a constructor for a class D, F2 is a constructor for a base class B
>> + of D, and for all arguments the corresponding parameters of F1 and F2 have
>> + the same type (CWG 2273/2277). */
>> + if (DECL_P (cand1->fn) && DECL_CONSTRUCTOR_P (cand1->fn)
>> + && DECL_P (cand2->fn) && DECL_CONSTRUCTOR_P (cand2->fn))
>
> Here's v2 which refines this condition to check DECL_INHERITED_CTOR
> instead. No functional change, but this more narrow condition seems
> cleaner.
OK.
> -- >8 --
>
> Subject: [PATCH 1/2] c++: CWG 2273 and non-constructors
>
> Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
> incorrectly considering all member functions introduced via using, not
> just constructors. This patch restricts the tiebreaker accordingly.
>
> DR 2273
>
> gcc/cp/ChangeLog:
>
> * call.cc (joust): Restrict inheritedness tiebreaker to
> constructors.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
> * g++.dg/overload/using5.C: Likewise.
> ---
> gcc/cp/call.cc | 11 ++++-------
> gcc/testsuite/g++.dg/cpp1z/using1.C | 8 ++++----
> gcc/testsuite/g++.dg/overload/using5.C | 2 +-
> 3 files changed, 9 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> index 3f753e2d2f9..6229dc45263 100644
> --- a/gcc/cp/call.cc
> +++ b/gcc/cp/call.cc
> @@ -13350,13 +13350,10 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
> }
> }
>
> - /* F1 is a member of a class D, F2 is a member of a base class B of D, and
> - for all arguments the corresponding parameters of F1 and F2 have the same
> - type (CWG 2273/2277). */
> - if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
> - && !DECL_CONV_FN_P (cand1->fn)
> - && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
> - && !DECL_CONV_FN_P (cand2->fn))
> + /* F1 is a constructor for a class D, F2 is a constructor for a base class B
> + of D, and for all arguments the corresponding parameters of F1 and F2 have
> + the same type (CWG 2273/2277). */
> + if (DECL_INHERITED_CTOR (cand1->fn) || DECL_INHERITED_CTOR (cand2->fn))
> {
> tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
> tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
> diff --git a/gcc/testsuite/g++.dg/cpp1z/using1.C b/gcc/testsuite/g++.dg/cpp1z/using1.C
> index 1ed939d45fd..d8a04525579 100644
> --- a/gcc/testsuite/g++.dg/cpp1z/using1.C
> +++ b/gcc/testsuite/g++.dg/cpp1z/using1.C
> @@ -1,5 +1,5 @@
> -// Test for hiding of used base functions when all the conversion sequences are
> -// equivalent, needed to avoid a regression on inherited default ctors.
> +// Test the CWG 2273 inheritedness tiebreaker doesn't apply to
> +// non-constructors.
>
> struct A
> {
> @@ -17,7 +17,7 @@ struct B:A
>
> int main()
> {
> - B().f(1); // OK, derived f hides base f for single arg
> + B().f(1); // { dg-error "ambiguous" }
> B().f(1,2); // OK, base f can still be called with two args
> - B().g(1); // { dg-error "" } signatures differ, ambiguous
> + B().g(1); // { dg-error "ambiguous" }
> }
> diff --git a/gcc/testsuite/g++.dg/overload/using5.C b/gcc/testsuite/g++.dg/overload/using5.C
> index ad17c78a561..0933a9f0fac 100644
> --- a/gcc/testsuite/g++.dg/overload/using5.C
> +++ b/gcc/testsuite/g++.dg/overload/using5.C
> @@ -24,5 +24,5 @@ struct C: B {
> int main()
> {
> C c (42);
> - c.f();
> + c.f(); // { dg-error "ambiguous" }
> }
@@ -13350,13 +13350,11 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
}
}
- /* F1 is a member of a class D, F2 is a member of a base class B of D, and
- for all arguments the corresponding parameters of F1 and F2 have the same
- type (CWG 2273/2277). */
- if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
- && !DECL_CONV_FN_P (cand1->fn)
- && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
- && !DECL_CONV_FN_P (cand2->fn))
+ /* F1 is a constructor for a class D, F2 is a constructor for a base class B
+ of D, and for all arguments the corresponding parameters of F1 and F2 have
+ the same type (CWG 2273/2277). */
+ if (DECL_P (cand1->fn) && DECL_CONSTRUCTOR_P (cand1->fn)
+ && DECL_P (cand2->fn) && DECL_CONSTRUCTOR_P (cand2->fn))
{
tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
@@ -1,5 +1,4 @@
-// Test for hiding of used base functions when all the conversion sequences are
-// equivalent, needed to avoid a regression on inherited default ctors.
+// Test the CWG 2237 resolution doesn't apply to inherited non-constructors.
struct A
{
@@ -17,7 +16,7 @@ struct B:A
int main()
{
- B().f(1); // OK, derived f hides base f for single arg
+ B().f(1); // { dg-error "ambiguous" }
B().f(1,2); // OK, base f can still be called with two args
- B().g(1); // { dg-error "" } signatures differ, ambiguous
+ B().g(1); // { dg-error "ambiguous" } signatures differ
}
@@ -24,5 +24,5 @@ struct C: B {
int main()
{
C c (42);
- c.f();
+ c.f(); // { dg-error "ambiguous" }
}