Skip to content

Commit 2299a2d

Browse files
committed
Fix internal compiler error with certain kinds of INOUT parameters (issue #146)
1 parent 46d3c52 commit 2299a2d

File tree

4 files changed

+15
-1
lines changed

4 files changed

+15
-1
lines changed

Diff for: src/analyzer.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,9 @@ const ast::Expression *Analyzer::analyze(const pt::FunctionCallExpression *expr)
15611561
if (not e->type->is_assignment_compatible(ftype->params[p]->type)) {
15621562
error2(3194, a->expr->token, "type mismatch", ftype->params[p]->declaration, "function argument here");
15631563
}
1564+
if (ftype->params[p]->mode == ast::ParameterType::INOUT && not ref->can_generate_address()) {
1565+
error(3241, a->expr->token, "using this kind of expression with an INOUT parameter is currently not supported");
1566+
}
15641567
}
15651568
if (ftype->params[p]->mode == ast::ParameterType::OUT && a->mode.type != OUT) {
15661569
error(3184, a->expr->token, "OUT keyword required");

Diff for: src/ast.h

+5
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,7 @@ class ReferenceExpression: public Expression {
16291629
ReferenceExpression(const Type *type, bool is_readonly): Expression(type, false, is_readonly) {}
16301630

16311631
virtual void generate_expr(Emitter &emitter) const override { generate_load(emitter); }
1632+
virtual bool can_generate_address() const { return true; }
16321633
virtual void generate_address_read(Emitter &) const = 0;
16331634
virtual void generate_address_write(Emitter &) const = 0;
16341635
virtual void generate_load(Emitter &) const;
@@ -1646,6 +1647,7 @@ class DummyExpression: public ReferenceExpression {
16461647
virtual bool eval_boolean() const override { internal_error("DummyExpression"); }
16471648
virtual Number eval_number() const override { internal_error("DummyExpression"); }
16481649
virtual std::string eval_string() const override { internal_error("DummyExpression"); }
1650+
virtual bool can_generate_address() const { return false; }
16491651
virtual void generate_address_read(Emitter &) const override { internal_error("DummyExpression"); }
16501652
virtual void generate_address_write(Emitter &) const override { internal_error("DummyExpression"); }
16511653
virtual void generate_load(Emitter &) const override { internal_error("DummyExpression"); }
@@ -1751,6 +1753,7 @@ class StringReferenceIndexExpression: public ReferenceExpression {
17511753
virtual bool eval_boolean() const override { internal_error("StringReferenceIndexExpression"); }
17521754
virtual Number eval_number() const override { internal_error("StringReferenceIndexExpression"); }
17531755
virtual std::string eval_string() const override { internal_error("StringReferenceIndexExpression"); }
1756+
virtual bool can_generate_address() const { return false; }
17541757
virtual void generate_address_read(Emitter &) const override { internal_error("StringReferenceIndexExpression"); }
17551758
virtual void generate_address_write(Emitter &) const override { internal_error("StringReferenceIndexExpression"); }
17561759
virtual void generate_load(Emitter &) const override;
@@ -1803,6 +1806,7 @@ class BytesReferenceIndexExpression: public ReferenceExpression {
18031806
virtual bool eval_boolean() const override { internal_error("BytesReferenceIndexExpression"); }
18041807
virtual Number eval_number() const override { internal_error("BytesReferenceIndexExpression"); }
18051808
virtual std::string eval_string() const override { internal_error("BytesReferenceIndexExpression"); }
1809+
virtual bool can_generate_address() const { return false; }
18061810
virtual void generate_address_read(Emitter &) const override { internal_error("BytesReferenceIndexExpression"); }
18071811
virtual void generate_address_write(Emitter &) const override { internal_error("BytesReferenceIndexExpression"); }
18081812
virtual void generate_load(Emitter &) const override;
@@ -1896,6 +1900,7 @@ class ArrayReferenceRangeExpression: public ReferenceExpression {
18961900
virtual bool eval_boolean() const override { internal_error("ArrayReferenceRangeExpression"); }
18971901
virtual Number eval_number() const override { internal_error("ArrayReferenceRangeExpression"); }
18981902
virtual std::string eval_string() const override { internal_error("ArrayReferenceRangeExpression"); }
1903+
virtual bool can_generate_address() const { return false; }
18991904
virtual void generate_address_read(Emitter &) const override { internal_error("StringReferenceRangeExpression"); }
19001905
virtual void generate_address_write(Emitter &) const override { internal_error("StringReferenceRangeExpression"); }
19011906
virtual void generate_load(Emitter &) const override;

Diff for: t/errors/N3241.neon

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FUNCTION a_inout(INOUT p: Array<Number>)
2+
END FUNCTION
3+
4+
VAR a: Array<Number> := []
5+
a_inout(INOUT a[0 TO 4])
6+
%<

Diff for: t/parameter-inout-array.neon

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
% TODO
1+
% TODO https://github.com/ghewgill/neon-lang/issues/146
22
FUNCTION a_inout(INOUT p: Array<Number>)
33
p := [1, 2]
44
END FUNCTION

0 commit comments

Comments
 (0)