Skip to content

Commit 5a0144f

Browse files
committed
fix(cpp1): emit converting assignment from converting constructor
1 parent 5a57f5e commit 5a0144f

24 files changed

+101
-87
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
quantity: type = {
2+
value: int = ();
3+
operator=: (out this, val: int) = { value = val; }
4+
}
5+
6+
main: () = {
7+
x := quantity(0);
8+
static_assert(!std::is_assignable_v<decltype((x)), int>);
9+
_ = x;
10+
}

regression-tests/pure2-defaulted-comparisons-and-final-types.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ widget: final type =
33
{
44
v: int;
55

6-
operator=: (out this, value: int) = { v = value; }
6+
operator=: (implicit out this, value: int) = { v = value; }
77

88
operator==: (this, that) -> bool;
99

regression-tests/pure2-types-basics.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ myclass : type = {
1010
print();
1111
}
1212

13-
operator=: (out this, s: std::string) = {
13+
operator=: (implicit out this, s: std::string) = {
1414
this.data = 99;
1515
this.more = s;
1616
std::cout << "myclass: explicit from string\n";

regression-tests/pure2-types-smf-and-that-1-provide-everything.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ myclass : type = {
1919
std::cout << "assign - move ";
2020
}
2121

22-
operator=: (out this, x: std::string) = {
22+
operator=: (implicit out this, x: std::string) = {
2323
name = x;
2424
std::cout << "ctor - from string ";
2525
}

regression-tests/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ myclass : type = {
1919
// std::cout << "assign - move ";
2020
// }
2121

22-
operator=: (out this, x: std::string) = {
22+
operator=: (implicit out this, x: std::string) = {
2323
name = x;
2424
std::cout << "ctor - from string ";
2525
}

regression-tests/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ myclass : type = {
1919
std::cout << "assign - move ";
2020
}
2121

22-
operator=: (out this, x: std::string) = {
22+
operator=: (implicit out this, x: std::string) = {
2323
name = x;
2424
std::cout << "ctor - from string ";
2525
}

regression-tests/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ myclass : type = {
1919
std::cout << "assign - move ";
2020
}
2121

22-
operator=: (out this, x: std::string) = {
22+
operator=: (implicit out this, x: std::string) = {
2323
name = x;
2424
std::cout << "ctor - from string ";
2525
}

regression-tests/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ myclass : type = {
1919
// std::cout << "assign - move ";
2020
// }
2121

22-
operator=: (out this, x: std::string) = {
22+
operator=: (implicit out this, x: std::string) = {
2323
name = x;
2424
std::cout << "ctor - from string ";
2525
}

regression-tests/test-results/gcc-13/pure2-bugfix-for-explicit-converting-assignment.cpp.execution

Whitespace-only changes.

regression-tests/test-results/gcc-13/pure2-bugfix-for-explicit-converting-assignment.cpp.output

Whitespace-only changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
#define CPP2_USE_MODULES Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
#line 1 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
10+
class quantity;
11+
12+
13+
//=== Cpp2 type definitions and function declarations ===========================
14+
15+
#line 1 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
16+
class quantity {
17+
private: int value {};
18+
public: explicit quantity(cpp2::in<int> val);
19+
20+
public: quantity(quantity const&) = delete; /* No 'that' constructor, suppress copy */
21+
public: auto operator=(quantity const&) -> void = delete;
22+
#line 4 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
23+
};
24+
25+
auto main() -> int;
26+
27+
28+
//=== Cpp2 function definitions =================================================
29+
30+
31+
#line 3 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
32+
quantity::quantity(cpp2::in<int> val)
33+
: value{ val }
34+
#line 3 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
35+
{}
36+
37+
#line 6 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
38+
auto main() -> int{
39+
auto x {quantity(0)};
40+
static_assert(!(std::is_assignable_v<decltype((x)),int>));
41+
(void) std::move(x);
42+
}
43+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-bugfix-for-explicit-converting-assignment.cpp2... ok (all Cpp2, passes safety checks)
2+

regression-tests/test-results/pure2-defaulted-comparisons-and-final-types.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class widget final
1919
{
2020
private: int v;
2121

22-
public: explicit widget(cpp2::in<int> value);
22+
public: widget(cpp2::in<int> value);
2323
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
2424
public: auto operator=(cpp2::in<int> value) -> widget& ;
2525

@@ -40,13 +40,13 @@ auto main() -> int;
4040

4141
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
4242
widget::widget(cpp2::in<int> value)
43-
: v{ value }
43+
: v{ value }
4444
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
4545
{}
4646
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
4747
auto widget::operator=(cpp2::in<int> value) -> widget& {
48-
v = value;
49-
return *this;
48+
v = value;
49+
return *this;
5050
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
5151
}
5252

regression-tests/test-results/pure2-types-basics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class myclass {
3131

3232

3333
#line 13 "pure2-types-basics.cpp2"
34-
public: explicit myclass(cpp2::in<std::string> s);
34+
public: myclass(cpp2::in<std::string> s);
3535

3636
#line 13 "pure2-types-basics.cpp2"
3737
public: auto operator=(cpp2::in<std::string> s) -> myclass& ;

regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ class X {
4545
// Note: A constructor with an 'out' parameter
4646
public: explicit X(cpp2::out<Y> y);
4747

48-
#line 10 "pure2-types-order-independence-and-nesting.cpp2"
49-
public: auto operator=(cpp2::out<Y> y) -> X& ;
50-
5148

5249
#line 34 "pure2-types-order-independence-and-nesting.cpp2"
5350
// X::exx member function description here
@@ -66,8 +63,6 @@ class Y {
6663
private: X* px;
6764

6865
public: explicit Y(X* x);
69-
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
70-
public: auto operator=(X* x) -> Y& ;
7166

7267
public: auto why(cpp2::in<int> count) const -> void;
7368

@@ -139,16 +134,6 @@ namespace N {
139134
// then do anything else the constructor wants to do
140135
std::cout << "made a safely initialized cycle\n";
141136
}
142-
#line 10 "pure2-types-order-independence-and-nesting.cpp2"
143-
auto X::operator=(cpp2::out<Y> y) -> X& {
144-
y.construct(&(*this));
145-
py = &y.value();
146-
147-
#line 31 "pure2-types-order-independence-and-nesting.cpp2"
148-
std::cout << "made a safely initialized cycle\n";
149-
return *this;
150-
#line 32 "pure2-types-order-independence-and-nesting.cpp2"
151-
}
152137

153138
#line 35 "pure2-types-order-independence-and-nesting.cpp2"
154139
auto X::exx(cpp2::in<int> count) const -> void{
@@ -164,12 +149,6 @@ namespace N {
164149
: px{ x }
165150
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
166151
{ }
167-
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
168-
auto Y::operator=(X* x) -> Y& {
169-
px = x;
170-
return *this;
171-
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
172-
}
173152

174153
auto Y::why(cpp2::in<int> count) const -> void {
175154
CPP2_UFCS(exx, (*cpp2::assert_not_null(px)), count + 1); }// use X object from Y

regression-tests/test-results/pure2-types-ordering-via-meta-functions.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ class mystruct;
3030
class my_integer {
3131
private: int v;
3232
public: explicit my_integer(cpp2::in<int> val);
33-
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
34-
public: auto operator=(cpp2::in<int> val) -> my_integer& ;
3533

3634
public: [[nodiscard]] auto operator<=>(my_integer const& that) const -> std::strong_ordering = default;
3735

@@ -43,8 +41,6 @@ public: [[nodiscard]] auto operator<=>(my_integer const& that) const -> std::str
4341
class case_insensitive_string {
4442
private: std::string v; // case insensitive
4543
public: explicit case_insensitive_string(cpp2::in<std::string> val);
46-
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
47-
public: auto operator=(cpp2::in<std::string> val) -> case_insensitive_string& ;
4844

4945
public: [[nodiscard]] auto operator<=>(case_insensitive_string const& that) const -> std::weak_ordering = default;
5046

@@ -56,8 +52,6 @@ public: [[nodiscard]] auto operator<=>(case_insensitive_string const& that) cons
5652
class person_in_family_tree {
5753
private: int dummy_data;
5854
public: explicit person_in_family_tree(cpp2::in<int> parents);
59-
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
60-
public: auto operator=(cpp2::in<int> parents) -> person_in_family_tree& ;
6155

6256
public: [[nodiscard]] auto operator<=>(person_in_family_tree const& that) const -> std::partial_ordering = default;
6357

@@ -81,38 +75,20 @@ auto main() -> int;
8175
: v{ val }
8276
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
8377
{}
84-
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
85-
auto my_integer::operator=(cpp2::in<int> val) -> my_integer& {
86-
v = val;
87-
return *this;
88-
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
89-
}
9078

9179

9280
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
9381
case_insensitive_string::case_insensitive_string(cpp2::in<std::string> val)
9482
: v{ val }
9583
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
9684
{}
97-
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
98-
auto case_insensitive_string::operator=(cpp2::in<std::string> val) -> case_insensitive_string& {
99-
v = val;
100-
return *this;
101-
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
102-
}
10385

10486

10587
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
10688
person_in_family_tree::person_in_family_tree(cpp2::in<int> parents)
10789
: dummy_data{ parents }
10890
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
10991
{}
110-
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
111-
auto person_in_family_tree::operator=(cpp2::in<int> parents) -> person_in_family_tree& {
112-
dummy_data = parents;
113-
return *this;
114-
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
115-
}
11692

11793

11894
#line 21 "pure2-types-ordering-via-meta-functions.cpp2"

regression-tests/test-results/pure2-types-smf-and-that-1-provide-everything.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class myclass {
3333

3434

3535
#line 22 "pure2-types-smf-and-that-1-provide-everything.cpp2"
36-
public: explicit myclass(cpp2::in<std::string> x);
36+
public: myclass(cpp2::in<std::string> x);
3737

3838
#line 22 "pure2-types-smf-and-that-1-provide-everything.cpp2"
3939
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;

regression-tests/test-results/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class myclass {
3636
// std::cout << "assign - move ";
3737
// }
3838

39-
public: explicit myclass(cpp2::in<std::string> x);
39+
public: myclass(cpp2::in<std::string> x);
4040

4141
#line 22 "pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp2"
4242
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;

regression-tests/test-results/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class myclass {
3737

3838

3939
#line 22 "pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp2"
40-
public: explicit myclass(cpp2::in<std::string> x);
40+
public: myclass(cpp2::in<std::string> x);
4141

4242
#line 22 "pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp2"
4343
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;

regression-tests/test-results/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class myclass {
3737

3838

3939
#line 22 "pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp2"
40-
public: explicit myclass(cpp2::in<std::string> x);
40+
public: myclass(cpp2::in<std::string> x);
4141

4242
#line 22 "pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp2"
4343
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;

regression-tests/test-results/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class myclass {
4444
// std::cout << "assign - move ";
4545
// }
4646

47-
public: explicit myclass(cpp2::in<std::string> x);
47+
public: myclass(cpp2::in<std::string> x);
4848

4949
#line 22 "pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp2"
5050
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;

regression-tests/test-results/pure2-types-value-types-via-meta-functions.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ class p_widget;
2626
class widget {
2727
private: int val {0};
2828
public: explicit widget(cpp2::in<int> i);
29-
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
30-
public: auto operator=(cpp2::in<int> i) -> widget& ;
3129

3230
public: [[nodiscard]] auto operator<=>(widget const& that) const -> std::strong_ordering = default;
3331
public: widget(widget const& that);
@@ -42,8 +40,6 @@ public: explicit widget();
4240
class w_widget {
4341
private: int val {0};
4442
public: explicit w_widget(cpp2::in<int> i);
45-
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
46-
public: auto operator=(cpp2::in<int> i) -> w_widget& ;
4743

4844
public: [[nodiscard]] auto operator<=>(w_widget const& that) const -> std::weak_ordering = default;
4945
public: w_widget(w_widget const& that);
@@ -58,8 +54,6 @@ public: explicit w_widget();
5854
class p_widget {
5955
private: int val {0};
6056
public: explicit p_widget(cpp2::in<int> i);
61-
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
62-
public: auto operator=(cpp2::in<int> i) -> p_widget& ;
6357

6458
public: [[nodiscard]] auto operator<=>(p_widget const& that) const -> std::partial_ordering = default;
6559
public: p_widget(p_widget const& that);
@@ -86,12 +80,6 @@ template<typename T> auto test() -> void;
8680
: val{ i }
8781
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
8882
{}
89-
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
90-
auto widget::operator=(cpp2::in<int> i) -> widget& {
91-
val = i;
92-
return *this;
93-
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
94-
}
9583

9684

9785
widget::widget(widget const& that)
@@ -111,12 +99,6 @@ widget::widget(){}
11199
: val{ i }
112100
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
113101
{}
114-
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
115-
auto w_widget::operator=(cpp2::in<int> i) -> w_widget& {
116-
val = i;
117-
return *this;
118-
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
119-
}
120102

121103

122104
w_widget::w_widget(w_widget const& that)
@@ -136,12 +118,6 @@ w_widget::w_widget(){}
136118
: val{ i }
137119
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
138120
{}
139-
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
140-
auto p_widget::operator=(cpp2::in<int> i) -> p_widget& {
141-
val = i;
142-
return *this;
143-
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
144-
}
145121

146122

147123
p_widget::p_widget(p_widget const& that)

source/cppfront.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5464,9 +5464,10 @@ class cppfront
54645464
&& !current_functions.back().declared_that_functions.inout_this_in_that
54655465
)
54665466
||
5467-
// A3) This is '(out this, something-other-than-that)'
5467+
// A3) This is '(implicit out this, something-other-than-that)'
54685468
(
54695469
n.is_constructor()
5470+
&& n.is_function_with_implicit_this()
54705471
&& !n.is_constructor_with_that()
54715472
)
54725473
)

0 commit comments

Comments
 (0)