diff options
author | Jeremy Philippe <jeremy.philippe@gmail.com> | 2020-01-08 13:20:31 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2020-01-08 15:01:21 +0100 |
commit | 6cfa112524d13f878d02149475079e34cd366116 (patch) | |
tree | bdead6c5f096e01124912145d2c6d4fd1a27bcb6 | |
parent | 7850210bafcdd81f5b7a36b82766ae73f0fa0610 (diff) | |
download | vala-6cfa112524d13f878d02149475079e34cd366116.tar.gz |
vala: Non-nullable value-type in coalesce expression needs to be copied
The code generated by the coalesce expression could lead to stale
pointers to the stack if the right-side expression is an immediate value
(such as an integer literal or a struct).
Fixes https://gitlab.gnome.org/GNOME/vala/issues/893
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/control-flow/coalesce-right-value.vala | 17 | ||||
-rw-r--r-- | vala/valabinaryexpression.vala | 6 |
3 files changed, 24 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 2c66135bf..314b01439 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -166,6 +166,7 @@ TESTS = \ control-flow/break.vala \ control-flow/break-invalid.test \ control-flow/coalesce-reference-transfer.vala \ + control-flow/coalesce-right-value.vala \ control-flow/continue-invalid.test \ control-flow/double-catch.test \ control-flow/expressions-conditional.vala \ diff --git a/tests/control-flow/coalesce-right-value.vala b/tests/control-flow/coalesce-right-value.vala new file mode 100644 index 000000000..ca64126d7 --- /dev/null +++ b/tests/control-flow/coalesce-right-value.vala @@ -0,0 +1,17 @@ +struct Foo { + public int i; +} + +void main () { + { + int? null_int = null; + int i = null_int ?? 42; + assert (i == 42); + } + { + Foo? null_foo = null; + Foo right_foo = { 42 }; + Foo foo = null_foo ?? right_foo; + assert (foo.i == 42); + } +} diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index fe559e1d5..927ca5413 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -234,6 +234,12 @@ public class Vala.BinaryExpression : Expression { local_type = right.value_type.copy (); } + if (local_type != null && right.value_type is ValueType && !right.value_type.nullable) { + // immediate values in the right expression must always be boxed, + // otherwise the local variable may receive a stale pointer to the stack + local_type.value_owned = true; + } + var local = new LocalVariable (local_type, get_temp_name (), left, source_reference); var decl = new DeclarationStatement (local, source_reference); |