diff mbox

PR c++/67054 Allow inheriting constructor with non-default-constructible members

Message ID 84a1172988e14a7caf7c78cbaed2a3ff@uwaterloo.ca
State New
Headers show

Commit Message

Leonid Koppel July 26, 2017, 4:45 p.m. UTC
This patch addresses PR 67054 (duplicates 62310, 80851). An implicitly-defined inheriting constructor was wrongly considered deleted when it would initialize a non-default-constructible member, even when a brace-or-equal-initializer was present.

The bug only affects deduction of the constructor's deletedness, not the actual generation of the constructor, which is why (I hope!) the fix might be so simple.

Tested on x86_64-pc-linux-gnu native.

Thanks,
Leo

2017-07-26  Leonid Koppel  <lkoppel@uwaterloo.ca>

	PR c++/67054 - Inheriting constructor with non-default-constructible members
	* method.c (walk_field_subobs) Consider member initializers (NSDMIs) when 
	deducing an inheriting constructor.

Comments

Jason Merrill July 26, 2017, 4:52 p.m. UTC | #1
OK, thanks.

On Wed, Jul 26, 2017 at 12:45 PM, Leonid Koppel <lkoppel@uwaterloo.ca> wrote:
> This patch addresses PR 67054 (duplicates 62310, 80851). An implicitly-defined inheriting constructor was wrongly considered deleted when it would initialize a non-default-constructible member, even when a brace-or-equal-initializer was present.
>
> The bug only affects deduction of the constructor's deletedness, not the actual generation of the constructor, which is why (I hope!) the fix might be so simple.
>
> Tested on x86_64-pc-linux-gnu native.
>
> Thanks,
> Leo
>
> 2017-07-26  Leonid Koppel  <lkoppel@uwaterloo.ca>
>
>         PR c++/67054 - Inheriting constructor with non-default-constructible members
>         * method.c (walk_field_subobs) Consider member initializers (NSDMIs) when
>         deducing an inheriting constructor.
>
> diff --git a/gcc/cp/method.c b/gcc/cp/method.c
> index cca1b146917..8b07f526473 100644
> --- a/gcc/cp/method.c
> +++ b/gcc/cp/method.c
> @@ -1342,7 +1342,7 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
>           if (bad && deleted_p)
>             *deleted_p = true;
>         }
> -      else if (sfk == sfk_constructor)
> +      else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
>         {
>           bool bad;
>
> diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor29.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor29.C
> new file mode 100644
> index 00000000000..8e31f739d74
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor29.C
> @@ -0,0 +1,23 @@
> +// PR c++/67054
> +// { dg-do compile { target c++11 } }
> +
> +struct A
> +{
> +  A(int) {}
> +};
> +
> +struct C
> +{
> +  C(int) {}
> +};
> +
> +struct B : A
> +{
> +  using A::A;
> +  C c = 42;
> +};
> +
> +int main()
> +{
> +  B b = 24;
> +}
diff mbox

Patch

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index cca1b146917..8b07f526473 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1342,7 +1342,7 @@  walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
 	  if (bad && deleted_p)
 	    *deleted_p = true;
 	}
-      else if (sfk == sfk_constructor)
+      else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
 	{
 	  bool bad;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor29.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor29.C
new file mode 100644
index 00000000000..8e31f739d74
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor29.C
@@ -0,0 +1,23 @@ 
+// PR c++/67054
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  A(int) {}
+};
+
+struct C
+{
+  C(int) {}
+};
+
+struct B : A
+{
+  using A::A;
+  C c = 42;
+};
+
+int main()
+{
+  B b = 24;
+}