]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix binary operations between nullable types
authorLuca Bruno <lucabru@src.gnome.org>
Sat, 9 Apr 2011 10:22:04 +0000 (12:22 +0200)
committerLuca Bruno <lucabru@src.gnome.org>
Sat, 9 Apr 2011 11:21:28 +0000 (13:21 +0200)
Based on patch by Geert Jordaens.

Fixes bug 591552.

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/basic-types/bug591552.vala [new file with mode: 0644]
vala/valabinaryexpression.vala

index bed29d4fd6d45615f3f9311fba66c95caafa2056..3b6935725065cbbfd7fd3be7944f3ed28e118769 100644 (file)
@@ -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);
index f4bb5c12ed1ba7899cb221a0ad3b8eb98e86a6ff..c3c90d3ae1a070e34a2c4f64b2075707d594f997 100644 (file)
@@ -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 (file)
index 0000000..e51a48c
--- /dev/null
@@ -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;
+}
index 0b461049cb6cadf5e83fce71826424cbaba57501..2cddc2f0a5faac5bd6b3627f64d1ae598418cd9f 100644 (file)
@@ -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 ()));