@@ -1963,6 +1963,7 @@ $(GNAME PrimaryExpression):
1963
1963
$(GLINK IsExpression)
1964
1964
$(D $(LPAREN)) $(GLINK Expression) $(D $(RPAREN))
1965
1965
$(GLINK SpecialKeyword)
1966
+ $(GLINK RvalueExpression)
1966
1967
$(GLINK2 traits, TraitsExpression)
1967
1968
1968
1969
$(GNAME LiteralExpression):
@@ -3452,6 +3453,65 @@ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
3452
3453
)
3453
3454
3454
3455
3456
+ $(H3 $(LNAME2 RvalueExpression, Rvalue Expression))
3457
+
3458
+ $(GRAMMAR
3459
+ $(GNAME RvalueExpression):
3460
+ $(D __rvalue $(LPAREN)) $(GLINK AssignExpression) $(D $(RPAREN))
3461
+ )
3462
+
3463
+ $(P The $(I RvalueExpression) causes the embedded $(I AssignExpression) to be
3464
+ treated as an rvalue whether it is an rvalue or an lvalue.)
3465
+
3466
+ $(H4 Overloading)
3467
+
3468
+ $(P If both ref and non-ref parameter overloads are present, an rvalue is preferably matched to the
3469
+ non-ref parameters, and an lvalue is preferably matched to the ref parameter.
3470
+ An $(I RvalueExpression) will preferably match with the non-ref parameter.)
3471
+
3472
+ $(H4 Semantics of Arguments Matched to Rvalue Parameters)
3473
+
3474
+ $(P An rvalue argument is owned by the function called. Hence, if an lvalue is matched
3475
+ to the rvalue argument, a copy is made of the lvalue to be passed to the function. The function
3476
+ will then call the destructor (if any) on the parameter at the conclusion of the function.
3477
+ An rvalue argument is not copied, as it is assumed to already be unique, and is also destroyed at
3478
+ the conclusion of the function.)
3479
+
3480
+ $(P The called function's semantics are the same whether a parameter originated as an rvalue
3481
+ or is a copy of an lvalue.
3482
+ This means that an $(I RvalueExpression) argument destroys the expression upon function return.
3483
+ Attempts to continue to use the lvalue expression are invalid. The compiler won't always be able
3484
+ to detect a use after being passed to the function, which means that the destructor for the object
3485
+ must reset the object's contents to its initial value, or at least a benign value that can
3486
+ be destructed more than once.
3487
+ )
3488
+
3489
+ ---
3490
+ struct S
3491
+ {
3492
+ ubyte* p;
3493
+ ~this()
3494
+ {
3495
+ free(p);
3496
+ // add `p = null;` here to prevent double free
3497
+ }
3498
+ }
3499
+
3500
+ void aggh(S s)
3501
+ {
3502
+ }
3503
+
3504
+ void oops()
3505
+ {
3506
+ S s;
3507
+ s.p = cast(ubyte*)malloc(10);
3508
+ aggh(__rvalue(s));
3509
+ // destructor of s called at end of scope, double-freeing s.p
3510
+ }
3511
+ ---
3512
+
3513
+ $(P $(I RvalueExpression)s enable the use of $(I move constructor)s and $(I move assignment)s.)
3514
+
3455
3515
$(H3 $(LNAME2 specialkeywords, Special Keywords))
3456
3516
3457
3517
$(GRAMMAR
0 commit comments