Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions tslang/lib/TypeScript/MLIRGenExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ namespace mlirgen
}
else if (kind == SyntaxKind::DeleteExpression)
{
mlirGen(expressionAST.as<DeleteExpression>(), genContext);
// its failure was dropped, and with it the error: `delete n` of a local compiled
EXIT_IF_FAILED(mlirGen(expressionAST.as<DeleteExpression>(), genContext));
return mlir::success();
}
else if (kind == SyntaxKind::ThisKeyword)
Expand Down Expand Up @@ -1365,6 +1366,13 @@ namespace mlirgen
{
CAST(expr, location, mlir_ts::RefType::get(arrayType.getElementType()), expr, genContext);
}
else if (deleteExpression->expression == SyntaxKind::Identifier)
{
// `delete n` of a local holding a number: nothing to free (a class instance, an
// array or a value made by `new`, which can be freed, took the paths above)
emitError(location, "The operand of a 'delete' operator must be a property reference");
return mlir::failure();
}
else
{
// e.g. `delete obj.a` where `a` is a plain, non-optional field of a value-tuple
Expand Down Expand Up @@ -1409,8 +1417,11 @@ namespace mlirgen
if (reference && isOwningSlot(location, reference))
{
auto nullValue = builder.create<mlir_ts::NullOp>(location, getNullType());
mlir::Value clearedValue;
CAST(clearedValue, location, expr.getType(), nullValue, genContext);
// not a null the program stores, so no strict-null check: it failed this cast for
// `let c = new C()`, and the store was never made
auto clearedResult = cast(location, expr.getType(), nullValue, genContext, /*disableStrictNullCheck*/ true);
EXIT_IF_FAILED_OR_NO_VALUE(clearedResult)
auto clearedValue = V(clearedResult);
builder.create<mlir_ts::StoreOp>(location, clearedValue, reference);
}
}
Expand Down
10 changes: 10 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2930,6 +2930,16 @@ set_tests_properties(test-compile-diagnostic-location-generated-cast
PROPERTIES PASS_REGULAR_EXPRESSION "generated_cast\\.ts:6:23: error: can't cast from 'null' to 'string'"
FAIL_REGULAR_EXPRESSION "Stack dump|Assertion failed|generated_cast\\.ts:1:")

# `delete` of a local holding a number is an error: it compiled, as the error made for it was
# dropped. A class instance (or an array, or a value made by `new`) can still be deleted.
add_test(NAME test-compile-diagnostic-location-delete-local
COMMAND $<TARGET_FILE:tslang> --emit=obj --no-default-lib -mm=none
"${PROJECT_SOURCE_DIR}/test/tester/diagnostic-location/delete_local.ts"
-o "${CMAKE_CURRENT_BINARY_DIR}/diagnostic-location-delete-local.obj")
set_tests_properties(test-compile-diagnostic-location-delete-local
PROPERTIES PASS_REGULAR_EXPRESSION "delete_local\\.ts:9:5: error: The operand of a 'delete' operator must be a property reference"
FAIL_REGULAR_EXPRESSION "Stack dump|Assertion failed|delete_local\\.ts:7:")

# An error in a field initializer, or in a derived class's implicit constructor, is reported at the
# field or the class - not at 1:1, where the code the compiler generates for them had put it.
add_test(NAME test-compile-diagnostic-location-field-initializer
Expand Down
10 changes: 10 additions & 0 deletions tslang/test/tester/diagnostic-location/delete_local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// `delete` of a local holding a number compiled with no error: the error was made and dropped.

class C {}

function main() {
const c = new C();
delete c;
const n = 5;
delete n;
}
Loading