]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix binary 'in' operator on array with boxed value-typed needle 0a0a851198fb8dcc14e752a7e086418a69183511 120/head
authorAndrea Del Signore <sejerpz@gmail.com>
Fri, 3 Apr 2020 17:10:40 +0000 (19:10 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 11 Apr 2020 14:46:42 +0000 (16:46 +0200)
See https://gitlab.gnome.org/GNOME/vala/issues/951

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/arrays/in-operator-with-boxed-needle.vala [new file with mode: 0644]

index a921cd755398088be58d7772be6203c7e545ecdb..55911934145644b037b0a23c4a2b37c299bfb6c6 100644 (file)
@@ -5482,14 +5482,23 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        break;
                case BinaryOperator.IN:
                        if (expr.right.value_type is ArrayType) {
-                               var array_type = (ArrayType) expr.right.value_type;
-                               var node = new CCodeFunctionCall (new CCodeIdentifier (generate_array_contains_wrapper (array_type)));
-                               node.add_argument (cright);
-                               node.add_argument (get_array_length_cexpression (expr.right));
-                               if (array_type.element_type is StructValueType) {
-                                       node.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cleft));
+                               unowned ArrayType array_type = (ArrayType) expr.right.value_type;
+                               unowned DataType element_type = array_type.element_type;
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_array_contains_wrapper (array_type)));
+                               CCodeExpression node = ccall;
+
+                               ccall.add_argument (cright);
+                               ccall.add_argument (get_array_length_cexpression (expr.right));
+                               if (element_type is StructValueType) {
+                                       ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cleft));
+                               } else if (element_type is ValueType && !element_type.nullable
+                                       && expr.left.value_type is ValueType && expr.left.value_type.nullable) {
+                                       // null check
+                                       var cnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cleft, new CCodeConstant ("NULL"));
+                                       ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cleft));
+                                       node = new CCodeParenthesizedExpression (new CCodeConditionalExpression (cnull, new CCodeConstant ("FALSE"), ccall));
                                } else {
-                                       node.add_argument (cleft);
+                                       ccall.add_argument (cleft);
                                }
                                set_cvalue (expr, node);
                        } else {
index 083b320fb6b16af2af1a7c15ff15e8061c02d3cb..52b7bde0e64e131e74c00660f2aed28259fa9dd0 100644 (file)
@@ -88,6 +88,7 @@ TESTS = \
        arrays/inline-local-variable.test \
        arrays/inline-parameter.test \
        arrays/inline-struct-field.test \
+       arrays/in-operator-with-boxed-needle.vala \
        arrays/length-inline-assignment.vala \
        arrays/length-type-include.vala \
        arrays/struct-field-length-cname.vala \
diff --git a/tests/arrays/in-operator-with-boxed-needle.vala b/tests/arrays/in-operator-with-boxed-needle.vala
new file mode 100644 (file)
index 0000000..e3b129a
--- /dev/null
@@ -0,0 +1,12 @@
+void main () {
+       int[] foo = { 0, 23, 42 };
+
+       int? i = null;
+       assert (!(i in foo));
+
+       i = 23;
+       assert (i in foo);
+
+       i = 4711;
+       assert (!(i in foo));
+}