From 50748111d26d839cb8244e1bfc0c6924305a90b1 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Tue, 11 Apr 2017 17:19:58 +0200 Subject: [PATCH] vala: Handle non-null in coalescing expression https://bugzilla.gnome.org/show_bug.cgi?id=611223 --- tests/Makefile.am | 8 +++++++- tests/nullability/bug611223.vala | 7 +++++++ vala/valabinaryexpression.vala | 33 ++++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 tests/nullability/bug611223.vala diff --git a/tests/Makefile.am b/tests/Makefile.am index e368b6b95..2a2f4d43c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -286,11 +286,17 @@ TESTS = \ annotations/description.vala \ $(NULL) -check-TESTS: $(TESTS) +NON_NULL_TESTS = \ + nullability/bug611223.vala \ + $(NULL) + +check-TESTS: $(TESTS) $(NON_NULL_TESTS) @EXEEXT=$(EXEEXT) EXEEXT=$(EXEEXT) CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(srcdir)/testrunner.sh $(TESTS) + @EXEEXT=$(EXEEXT) EXEEXT=$(EXEEXT) CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' VALAFLAGS="--enable-experimental-non-null" $(srcdir)/testrunner.sh $(NON_NULL_TESTS) EXTRA_DIST = \ testrunner.sh \ $(TESTS) \ + $(NON_NULL_TESTS) \ $(NULL) diff --git a/tests/nullability/bug611223.vala b/tests/nullability/bug611223.vala new file mode 100644 index 000000000..9fbf30c07 --- /dev/null +++ b/tests/nullability/bug611223.vala @@ -0,0 +1,7 @@ +void main() { + string? nullable = null; + string non_null = nullable ?? ""; + string? some_null = nullable ?? null; + string also_non_null = null ?? non_null; + string really_non_null = non_null ?? nullable; +} diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index 82e605398..19287da85 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -210,12 +210,31 @@ public class Vala.BinaryExpression : Expression { } DataType local_type = null; - if (left.value_type != null) { + bool cast_non_null = false; + if (left.value_type is NullType && right.value_type != null) { + Report.warning (left.source_reference, "left operand is always null"); + local_type = right.value_type.copy (); + local_type.nullable = true; + if (!right.value_type.nullable) { + cast_non_null = true; + } + } else if (left.value_type != null) { local_type = left.value_type.copy (); if (right.value_type != null && right.value_type.value_owned) { // value owned if either left or right is owned local_type.value_owned = true; } + if (context.experimental_non_null) { + if (!local_type.nullable) { + Report.warning (left.source_reference, "left operand is never null"); + if (right.value_type != null && right.value_type.nullable) { + local_type.nullable = true; + cast_non_null = true; + } + } else if (right.value_type != null && !right.value_type.nullable) { + cast_non_null = true; + } + } } else if (right.value_type != null) { local_type = right.value_type.copy (); } @@ -246,10 +265,16 @@ public class Vala.BinaryExpression : Expression { return false; } - var temp_access = SemanticAnalyzer.create_temp_access (local, target_type); - temp_access.check (context); + var replace_expr = SemanticAnalyzer.create_temp_access (local, target_type); + if (cast_non_null && replace_expr.target_type != null) { + var cast = new CastExpression.non_null (replace_expr, source_reference); + cast.target_type = replace_expr.target_type.copy (); + cast.target_type.nullable = false; + replace_expr = cast; + } + replace_expr.check (context); - parent_node.replace_expression (this, temp_access); + parent_node.replace_expression (this, replace_expr); return true; } -- 2.47.2