Skip to content

Commit

Permalink
[error] Reject attempts to copy object storage.
Browse files Browse the repository at this point in the history
Fix #176
  • Loading branch information
pfusik committed Oct 9, 2024
1 parent 38cd525 commit 2e50202
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Sema.fu
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,9 @@ public class FuSema
case FuToken.Assign:
CheckLValue(left);
CoercePermanent(right, left.Type);
if (left.Type is FuStorageType && right is FuSymbolReference
&& !(left is FuSymbolReference symbol && symbol.Symbol is FuNamedValue storageDef && storageDef.IsAssignableStorage()))
ReportError(right, "Cannot copy object storage");
SetSharedAssign(left, right);
expr.Left = left;
expr.Right = right;
Expand Down Expand Up @@ -1462,6 +1465,8 @@ public class FuSema
if (!(expr.Value is FuLiteral literal) || !literal.IsDefaultValue())
ReportError(expr.Value, "Only null, zero and false supported as an array initializer");
}
else if (type is FuStorageType && expr.Value is FuSymbolReference)
ReportError(expr.Value, "Cannot copy object storage");
CoercePermanent(expr.Value, type);
}
}
Expand Down
18 changes: 13 additions & 5 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5601,11 +5601,17 @@ std::shared_ptr<FuExpr> FuSema::visitBinaryExpr(std::shared_ptr<FuBinaryExpr> ex
case FuToken::assign:
checkLValue(left.get());
coercePermanent(right.get(), left->type.get());
setSharedAssign(left.get(), right.get());
expr->left = left;
expr->right = right;
expr->type = left->type;
return expr;
{
const FuSymbolReference * symbol;
const FuNamedValue * storageDef;
if (dynamic_cast<const FuStorageType *>(left->type.get()) && dynamic_cast<const FuSymbolReference *>(right.get()) && !((symbol = dynamic_cast<const FuSymbolReference *>(left.get())) && (storageDef = dynamic_cast<const FuNamedValue *>(symbol->symbol)) && storageDef->isAssignableStorage()))
reportError(right.get(), "Cannot copy object storage");
setSharedAssign(left.get(), right.get());
expr->left = left;
expr->right = right;
expr->type = left->type;
return expr;
}
case FuToken::addAssign:
checkLValue(left.get());
if (left->type->id == FuId::stringStorageType)
Expand Down Expand Up @@ -5998,6 +6004,8 @@ void FuSema::visitVar(std::shared_ptr<FuVar> expr)
if (!(literal = dynamic_cast<const FuLiteral *>(expr->value.get())) || !literal->isDefaultValue())
reportError(expr->value.get(), "Only null, zero and false supported as an array initializer");
}
else if (dynamic_cast<const FuStorageType *>(type) && dynamic_cast<const FuSymbolReference *>(expr->value.get()))
reportError(expr->value.get(), "Cannot copy object storage");
coercePermanent(expr->value.get(), type);
}
}
Expand Down
4 changes: 4 additions & 0 deletions libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5743,6 +5743,8 @@ FuExpr VisitBinaryExpr(FuBinaryExpr expr)
case FuToken.Assign:
CheckLValue(left);
CoercePermanent(right, left.Type);
if (left.Type is FuStorageType && right is FuSymbolReference && !(left is FuSymbolReference symbol && symbol.Symbol is FuNamedValue storageDef && storageDef.IsAssignableStorage()))
ReportError(right, "Cannot copy object storage");
SetSharedAssign(left, right);
expr.Left = left;
expr.Right = right;
Expand Down Expand Up @@ -6097,6 +6099,8 @@ void VisitVar(FuVar expr)
if (!(expr.Value is FuLiteral literal) || !literal.IsDefaultValue())
ReportError(expr.Value, "Only null, zero and false supported as an array initializer");
}
else if (type is FuStorageType && expr.Value is FuSymbolReference)
ReportError(expr.Value, "Cannot copy object storage");
CoercePermanent(expr.Value, type);
}
}
Expand Down
6 changes: 6 additions & 0 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -6043,6 +6043,10 @@ export class FuSema
case FuToken.ASSIGN:
this.#checkLValue(left);
this.#coercePermanent(right, left.type);
let symbol;
let storageDef;
if (left.type instanceof FuStorageType && right instanceof FuSymbolReference && !((symbol = left) instanceof FuSymbolReference && (storageDef = symbol.symbol) instanceof FuNamedValue && storageDef.isAssignableStorage()))
this.#reportError(right, "Cannot copy object storage");
this.#setSharedAssign(left, right);
expr.left = left;
expr.right = right;
Expand Down Expand Up @@ -6430,6 +6434,8 @@ export class FuSema
if (!((literal = expr.value) instanceof FuLiteral) || !literal.isDefaultValue())
this.#reportError(expr.value, "Only null, zero and false supported as an array initializer");
}
else if (type instanceof FuStorageType && expr.value instanceof FuSymbolReference)
this.#reportError(expr.value, "Cannot copy object storage");
this.#coercePermanent(expr.value, type);
}
}
Expand Down
11 changes: 11 additions & 0 deletions test/error/ObjectStgCopy.fu
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class Test
{
public static bool Run()
{
Test() o;
Test() c = o; //ERROR: Cannot copy object storage
Test() t;
t = o; //ERROR: Cannot copy object storage
return true;
}
}

0 comments on commit 2e50202

Please sign in to comment.