[vala] Fix binary operations between nullable types
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] Fix binary operations between nullable types
- Date: Sat, 9 Apr 2011 11:22:56 +0000 (UTC)
commit 2d45d82676ea741c56c7f681a5ac792d1767ac0c
Author: Luca Bruno <lucabru src gnome org>
Date: Sat Apr 9 12:22:04 2011 +0200
Fix binary operations between nullable types
Based on patch by Geert Jordaens.
Fixes bug 591552.
codegen/valaccodebasemodule.vala | 2 +-
tests/Makefile.am | 1 +
tests/basic-types/bug591552.vala | 27 +++++++++++++++++++++++++++
vala/valabinaryexpression.vala | 37 +++++++++++++++++++++++++------------
4 files changed, 54 insertions(+), 13 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index bed29d4..3b69357 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4818,7 +4818,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
if (expr.chained) {
var lbe = (BinaryExpression) expr.left;
- var temp_decl = get_temp_variable (lbe.right.value_type, true, null, false);
+ var temp_decl = get_temp_variable (lbe.right.target_type, true, null, false);
emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var clbe = (CCodeBinaryExpression) get_cvalue (lbe);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f4bb5c1..c3c90d3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -20,6 +20,7 @@ TESTS = \
basic-types/strings.vala \
basic-types/arrays.vala \
basic-types/pointers.vala \
+ basic-types/bug591552.vala \
basic-types/bug595751.vala \
basic-types/bug596637.vala \
basic-types/bug596785.vala \
diff --git a/tests/basic-types/bug591552.vala b/tests/basic-types/bug591552.vala
new file mode 100644
index 0000000..e51a48c
--- /dev/null
+++ b/tests/basic-types/bug591552.vala
@@ -0,0 +1,27 @@
+void main () {
+ int a = 1, b = 2;
+ int? c = 3, d = 4;
+ bool? test = null;
+
+ a = 1; b = 2;
+ c = 3; d = 4;
+ test = false;
+
+ a = a + b;
+ a = b - c;
+ a = c & d;
+ c = a ^ b;
+ c = b | c;
+ c = c % d;
+
+ d %= c;
+ c |= a & d;
+
+ test = c in d;
+ test = b > d;
+ test = test || test;
+ test = b > c > d < a;
+
+ test = a == c;
+ test = c == d;
+}
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 0b46104..2cddc2f 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -243,6 +243,11 @@ public class Vala.BinaryExpression : Expression {
return false;
}
+ left.target_type = left.value_type.copy ();
+ left.target_type.value_owned = false;
+ right.target_type = right.value_type.copy ();
+ right.target_type.value_owned = false;
+
if (left.value_type.data_type == context.analyzer.string_type.data_type
&& operator == BinaryOperator.PLUS) {
// string concatenation
@@ -319,10 +324,13 @@ public class Vala.BinaryExpression : Expression {
value_type = context.analyzer.size_t_type;
}
}
+ } else {
+ left.target_type.nullable = false;
+ right.target_type.nullable = false;
}
if (value_type == null) {
- value_type = context.analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+ value_type = context.analyzer.get_arithmetic_result_type (left.target_type, right.target_type);
}
if (value_type == null) {
@@ -334,7 +342,10 @@ public class Vala.BinaryExpression : Expression {
|| operator == BinaryOperator.SHIFT_LEFT
|| operator == BinaryOperator.SHIFT_RIGHT
|| operator == BinaryOperator.BITWISE_XOR) {
- value_type = context.analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+ left.target_type.nullable = false;
+ right.target_type.nullable = false;
+
+ value_type = context.analyzer.get_arithmetic_result_type (left.target_type, right.target_type);
if (value_type == null) {
error = true;
@@ -353,11 +364,14 @@ public class Vala.BinaryExpression : Expression {
} else {
DataType resulting_type;
+ left.target_type.nullable = false;
+ right.target_type.nullable = false;
+
if (chained) {
var lbe = (BinaryExpression) left;
- resulting_type = context.analyzer.get_arithmetic_result_type (lbe.right.value_type, right.value_type);
+ resulting_type = context.analyzer.get_arithmetic_result_type (lbe.right.target_type, right.target_type);
} else {
- resulting_type = context.analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+ resulting_type = context.analyzer.get_arithmetic_result_type (left.target_type, right.target_type);
}
if (resulting_type == null) {
@@ -365,13 +379,6 @@ public class Vala.BinaryExpression : Expression {
Report.error (source_reference, "Relational operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
return false;
}
-
- left.target_type = left.value_type.copy ();
- left.target_type.nullable = false;
- left.target_type.value_owned = false;
- right.target_type = right.value_type.copy ();
- right.target_type.nullable = false;
- right.target_type.value_owned = false;
}
value_type = context.analyzer.bool_type;
@@ -424,20 +431,26 @@ public class Vala.BinaryExpression : Expression {
} else if (operator == BinaryOperator.BITWISE_AND
|| operator == BinaryOperator.BITWISE_OR) {
// integer type or flags type
+ left.target_type.nullable = false;
+ right.target_type.nullable = false;
- value_type = left.value_type;
+ value_type = left.target_type.copy ();
} else if (operator == BinaryOperator.AND
|| operator == BinaryOperator.OR) {
if (!left.value_type.compatible (context.analyzer.bool_type) || !right.value_type.compatible (context.analyzer.bool_type)) {
error = true;
Report.error (source_reference, "Operands must be boolean");
}
+ left.target_type.nullable = false;
+ right.target_type.nullable = false;
value_type = context.analyzer.bool_type;
} else if (operator == BinaryOperator.IN) {
if (left.value_type.compatible (context.analyzer.int_type)
&& right.value_type.compatible (context.analyzer.int_type)) {
// integers or enums
+ left.target_type.nullable = false;
+ right.target_type.nullable = false;
} else if (right.value_type is ArrayType) {
if (!left.value_type.compatible (((ArrayType) right.value_type).element_type)) {
Report.error (source_reference, "Cannot look for `%s' in `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]