@@ -2008,6 +2008,7 @@ $(GNAME PrimaryExpression):
2008
2008
$(GLINK IsExpression)
2009
2009
$(D $(LPAREN)) $(GLINK Expression) $(D $(RPAREN))
2010
2010
$(GLINK SpecialKeyword)
2011
+ $(GLINK RvalueExpression)
2011
2012
$(GLINK2 traits, TraitsExpression)
2012
2013
2013
2014
$(GNAME LiteralExpression):
@@ -3534,6 +3535,65 @@ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
3534
3535
)
3535
3536
3536
3537
3538
+ $(H3 $(LNAME2 RvalueExpression, Rvalue Expression))
3539
+
3540
+ $(GRAMMAR
3541
+ $(GNAME RvalueExpression):
3542
+ $(D __rvalue $(LPAREN)) $(GLINK AssignExpression) $(D $(RPAREN))
3543
+ )
3544
+
3545
+ $(P The $(I RvalueExpression) causes the embedded $(I AssignExpression) to be
3546
+ treated as an rvalue whether it is an rvalue or an lvalue.)
3547
+
3548
+ $(H4 Overloading)
3549
+
3550
+ $(P If both ref and non-ref parameter overloads are present, an rvalue is preferably matched to the
3551
+ non-ref parameters, and an lvalue is preferably matched to the ref parameter.
3552
+ An $(I RvalueExpression) will preferably match with the non-ref parameter.)
3553
+
3554
+ $(H4 Semantics of Arguments Matched to Rvalue Parameters)
3555
+
3556
+ $(P An rvalue argument is owned by the function called. Hence, if an lvalue is matched
3557
+ to the rvalue argument, a copy is made of the lvalue to be passed to the function. The function
3558
+ will then call the destructor (if any) on the parameter at the conclusion of the function.
3559
+ An rvalue argument is not copied, as it is assumed to already be unique, and is also destroyed at
3560
+ the conclusion of the function.)
3561
+
3562
+ $(P The called function's semantics are the same whether a parameter originated as an rvalue
3563
+ or is a copy of an lvalue.
3564
+ This means that an $(I RvalueExpression) argument destroys the expression upon function return.
3565
+ Attempts to continue to use the lvalue expression are invalid. The compiler won't always be able
3566
+ to detect a use after being passed to the function, which means that the destructor for the object
3567
+ must reset the object's contents to its initial value, or at least a benign value that can
3568
+ be destructed more than once.
3569
+ )
3570
+
3571
+ ---
3572
+ struct S
3573
+ {
3574
+ ubyte* p;
3575
+ ~this()
3576
+ {
3577
+ free(p);
3578
+ // add `p = null;` here to prevent double free
3579
+ }
3580
+ }
3581
+
3582
+ void aggh(S s)
3583
+ {
3584
+ }
3585
+
3586
+ void oops()
3587
+ {
3588
+ S s;
3589
+ s.p = cast(ubyte*)malloc(10);
3590
+ aggh(__rvalue(s));
3591
+ // destructor of s called at end of scope, double-freeing s.p
3592
+ }
3593
+ ---
3594
+
3595
+ $(P $(I RvalueExpression)s enable the use of $(I move constructor)s and $(I move assignment)s.)
3596
+
3537
3597
$(H3 $(LNAME2 specialkeywords, Special Keywords))
3538
3598
3539
3599
$(GRAMMAR
0 commit comments