[vala/staging] codegen: Fix binary 'in' operator on array with boxed value-typed needle



commit 0a0a851198fb8dcc14e752a7e086418a69183511
Author: Andrea Del Signore <sejerpz gmail com>
Date:   Fri Apr 3 19:10:40 2020 +0200

    codegen: Fix binary 'in' operator on array with boxed value-typed needle
    
    See https://gitlab.gnome.org/GNOME/vala/issues/951

 codegen/valaccodebasemodule.vala                | 23 ++++++++++++++++-------
 tests/Makefile.am                               |  1 +
 tests/arrays/in-operator-with-boxed-needle.vala | 12 ++++++++++++
 3 files changed, 29 insertions(+), 7 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a921cd755..559119341 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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 {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 083b320fb..52b7bde0e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 000000000..e3b129a19
--- /dev/null
+++ b/tests/arrays/in-operator-with-boxed-needle.vala
@@ -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));
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]