Skip to content

Commit

Permalink
2nd try at __rvalue(expression)
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Dec 8, 2024
1 parent 2674d22 commit 8ea2029
Show file tree
Hide file tree
Showing 23 changed files with 125 additions and 122 deletions.
1 change: 1 addition & 0 deletions compiler/src/dmd/astbase.d
Original file line number Diff line number Diff line change
Expand Up @@ -4548,6 +4548,7 @@ struct ASTBase
EXP op;
ubyte size;
ubyte parens;
ubyte rvalue; // consider this an rvalue, even if it is an lvalue
Type type;
Loc loc;

Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dmd/clone.d
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,7 @@ private Statement generateCopyCtorBody(StructDeclaration sd)
*/
bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)
{
//printf("needCopyCtor() %s\n", sd.toChars());
if (global.errors)
return false;

Expand Down Expand Up @@ -1655,7 +1656,7 @@ bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)

if (cpCtor)
{
if (rvalueCtor)
if (0 && rvalueCtor)
{
.error(sd.loc, "`struct %s` may not define both a rvalue constructor and a copy constructor", sd.toChars());
errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ class CtorDeclaration final : public FuncDeclaration
{
public:
d_bool isCpCtor;
d_bool isMoveCtor;
CtorDeclaration *syntaxCopy(Dsymbol *) override;
const char *kind() const override;
const char *toChars() const override;
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/dscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import dmd.dclass;
import dmd.declaration;
import dmd.dmodule;
import dmd.doc;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
Expand Down Expand Up @@ -146,6 +147,7 @@ extern (C++) struct Scope

AliasDeclaration aliasAsg; /// if set, then aliasAsg is being assigned a new value,
/// do not set wasRead for it
StructDeclaration argStruct; /// elimiate recursion when looking for rvalue construction

extern (D) __gshared Scope* freelist;

Expand Down
7 changes: 5 additions & 2 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2484,10 +2484,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
//printf("tf: %s\n", tf.toChars());
auto param = tf.parameterList[0];
if (param.storageClass & STC.ref_ && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
{
//printf("copy constructor\n");
ctd.isCpCtor = true;
if (param.storageClass & STC.ref_)
ctd.isCpCtor = true; // copy constructor

Check warning on line 2491 in compiler/src/dmd/dsymbolsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/dsymbolsem.d#L2491

Added line #L2491 was not covered by tests
else
ctd.isMoveCtor = true; // move constructor

Check warning on line 2493 in compiler/src/dmd/dsymbolsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/dsymbolsem.d#L2493

Added line #L2493 was not covered by tests
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/e2ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -5532,6 +5532,8 @@ elem *callfunc(const ref Loc loc,
v = ve.var.isVarDeclaration();
bool copy = !(v && (v.isArgDtorVar || v.storage_class & STC.rvalue)); // copy unless the destructor is going to be run on it
// then assume the frontend took care of the copying and pass it by ref
if (arg.rvalue) // marked with __rvalue
copy = false;

Check warning on line 5536 in compiler/src/dmd/e2ir.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/e2ir.d#L5536

Added line #L5536 was not covered by tests

elems[i] = addressElem(ea, arg.type, copy);
continue;
Expand Down
39 changes: 24 additions & 15 deletions compiler/src/dmd/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ extern (C++) abstract class Expression : ASTNode
Loc loc; // file location
const EXP op; // to minimize use of dynamic_cast
bool parens; // if this is a parenthesized expression
bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue

extern (D) this(const ref Loc loc, EXP op) scope @safe
{
Expand Down Expand Up @@ -1307,7 +1308,7 @@ extern (C++) class IdentifierExp : Expression

override final bool isLvalue()
{
return true;
return !this.rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -1351,7 +1352,7 @@ extern (C++) final class DsymbolExp : Expression

override bool isLvalue()
{
return true;
return !rvalue;

Check warning on line 1355 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L1355

Added line #L1355 was not covered by tests
}

override void accept(Visitor v)
Expand Down Expand Up @@ -1397,7 +1398,7 @@ extern (C++) class ThisExp : Expression
override final bool isLvalue()
{
// Class `this` should be an rvalue; struct `this` should be an lvalue.
return type.toBasetype().ty != Tclass;
return !rvalue && type.toBasetype().ty != Tclass;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -1782,7 +1783,7 @@ extern (C++) final class StringExp : Expression
/* string literal is rvalue in default, but
* conversion to reference of static array is only allowed.
*/
return (type && type.toBasetype().ty == Tsarray);
return !rvalue && (type && type.toBasetype().ty == Tsarray);
}

/********************************
Expand Down Expand Up @@ -2719,7 +2720,7 @@ extern (C++) final class VarExp : SymbolExp

override bool isLvalue()
{
if (var.storage_class & (STC.lazy_ | STC.rvalue | STC.manifest))
if (rvalue || var.storage_class & (STC.lazy_ | STC.rvalue | STC.manifest))
return false;
return true;
}
Expand Down Expand Up @@ -3098,7 +3099,7 @@ extern (C++) class BinAssignExp : BinExp

override final bool isLvalue()
{
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -3303,6 +3304,8 @@ extern (C++) final class DotVarExp : UnaExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 3308 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L3308

Added line #L3308 was not covered by tests
if (e1.op != EXP.structLiteral)
return true;
auto vd = var.isVarDeclaration();
Expand Down Expand Up @@ -3530,6 +3533,8 @@ extern (C++) final class CallExp : UnaExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 3537 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L3537

Added line #L3537 was not covered by tests
Type tb = e1.type.toBasetype();
if (tb.ty == Tdelegate || tb.ty == Tpointer)
tb = tb.nextOf();
Expand Down Expand Up @@ -3648,7 +3653,7 @@ extern (C++) final class PtrExp : UnaExp

override bool isLvalue()
{
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -3777,7 +3782,7 @@ extern (C++) final class CastExp : UnaExp
override bool isLvalue()
{
//printf("e1.type = %s, to.type = %s\n", e1.type.toChars(), to.toChars());
if (!e1.isLvalue())
if (rvalue || !e1.isLvalue())
return false;
return (to.ty == Tsarray && (e1.type.ty == Tvector || e1.type.ty == Tsarray)) ||
e1.type.mutableOf.unSharedOf().equals(to.mutableOf().unSharedOf());
Expand Down Expand Up @@ -3834,7 +3839,7 @@ extern (C++) final class VectorArrayExp : UnaExp

override bool isLvalue()
{
return e1.isLvalue();
return !rvalue && e1.isLvalue();
}

override void accept(Visitor v)
Expand Down Expand Up @@ -3891,7 +3896,7 @@ extern (C++) final class SliceExp : UnaExp
/* slice expression is rvalue in default, but
* conversion to reference of static array is only allowed.
*/
return (type && type.toBasetype().ty == Tsarray);
return !rvalue && (type && type.toBasetype().ty == Tsarray);
}

override Optional!bool toBool()
Expand Down Expand Up @@ -3956,6 +3961,8 @@ extern (C++) final class ArrayExp : UnaExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 3965 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L3964-L3965

Added lines #L3964 - L3965 were not covered by tests
if (type && type.toBasetype().ty == Tvoid)
return false;
return true;
Expand Down Expand Up @@ -4005,7 +4012,7 @@ extern (C++) final class CommaExp : BinExp

override bool isLvalue()
{
return e2.isLvalue();
return !rvalue && e2.isLvalue();
}

override Optional!bool toBool()
Expand Down Expand Up @@ -4080,7 +4087,7 @@ extern (C++) final class DelegatePtrExp : UnaExp

override bool isLvalue()
{
return e1.isLvalue();
return !rvalue && e1.isLvalue();
}

override void accept(Visitor v)
Expand All @@ -4103,7 +4110,7 @@ extern (C++) final class DelegateFuncptrExp : UnaExp

override bool isLvalue()
{
return e1.isLvalue();
return !rvalue && e1.isLvalue();

Check warning on line 4113 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L4113

Added line #L4113 was not covered by tests
}

override void accept(Visitor v)
Expand Down Expand Up @@ -4143,6 +4150,8 @@ extern (C++) final class IndexExp : BinExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 4154 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L4154

Added line #L4154 was not covered by tests
auto t1b = e1.type.toBasetype();
if (t1b.isTypeAArray() || t1b.isTypeSArray() ||
(e1.isIndexExp() && t1b != t1b.isTypeDArray()))
Expand Down Expand Up @@ -4251,7 +4260,7 @@ extern (C++) class AssignExp : BinExp
{
return false;
}
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -4982,7 +4991,7 @@ extern (C++) final class CondExp : BinExp

override bool isLvalue()
{
return e1.isLvalue() && e2.isLvalue();
return !rvalue && e1.isLvalue() && e2.isLvalue();
}

override void accept(Visitor v)
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class Expression : public ASTNode
Loc loc; // file location
EXP op; // to minimize use of dynamic_cast
d_bool parens; // if this is a parenthesized expression
d_bool rvalue; // consider this an rvalue, even if it is an lvalue

size_t size() const;
static void _init();
Expand Down
9 changes: 6 additions & 3 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ extern (D) Expression doCopyOrMove(Scope *sc, Expression e, Type t = null)
*/
private Expression callCpCtor(Scope* sc, Expression e, Type destinationType)
{
//printf("callCpCtor(e: %s et: %s destinationType: %s\n", toChars(e), toChars(e.type), toChars(destinationType));
auto ts = e.type.baseElemOf().isTypeStruct();

if (!ts)
Expand Down Expand Up @@ -2952,7 +2953,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
Type* prettype, Expression* peprefix)
{
Expressions* arguments = argumentList.arguments;
//printf("functionParameters() %s\n", fd ? fd.toChars() : "");
//printf("functionParameters() fd: %s tf: %s\n", fd ? fd.ident.toChars() : "", toChars(tf));
assert(arguments);
assert(fd || tf.next);
const size_t nparams = tf.parameterList.length;
Expand Down Expand Up @@ -3892,6 +3893,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}

scope (success) result.rvalue = exp.rvalue;

Dsymbol scopesym;
Dsymbol s = sc.search(exp.loc, exp.ident, scopesym);
if (s)
Expand Down Expand Up @@ -6718,7 +6721,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
errorSupplemental(exp.loc, "%s", failMessage);
}

if (tf.callMatch(null, exp.argumentList, 0, &errorHelper, sc) == MATCH.nomatch)
if (callMatch(exp.f, tf, null, exp.argumentList, 0, &errorHelper, sc) == MATCH.nomatch)
return setError();

// Purity and safety check should run after testing arguments matching
Expand Down Expand Up @@ -6801,7 +6804,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.f = null;
}

if (tf.callMatch(null, exp.argumentList, 0, &errorHelper2, sc) == MATCH.nomatch)
if (callMatch(exp.f, tf, null, exp.argumentList, 0, &errorHelper2, sc) == MATCH.nomatch)
exp.f = null;
}
if (!exp.f || exp.f.errors)
Expand Down
Loading

0 comments on commit 8ea2029

Please sign in to comment.