From: Jürg Billeter Date: Fri, 29 Jan 2010 16:23:29 +0000 (+0100) Subject: Support equality checking on nullable boolean and numeric types X-Git-Tag: 0.7.10~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a597f879078b5785489dfcaa316b78bae033bcc;p=thirdparty%2Fvala.git Support equality checking on nullable boolean and numeric types Fixes bug 608434. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index a3746798b..af186bda6 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2471,6 +2471,62 @@ internal class Vala.CCodeBaseModule : CCodeModule { return equal_func; } + private string generate_numeric_equal_function (Struct st) { + string equal_func = "_%sequal".printf (st.get_lower_case_cprefix ()); + + if (!add_wrapper (equal_func)) { + // wrapper already defined + return equal_func; + } + // declaration + + var function = new CCodeFunction (equal_func, "gboolean"); + function.modifiers = CCodeModifiers.STATIC; + + function.add_parameter (new CCodeFormalParameter ("s1", "const " + st.get_cname () + "*")); + function.add_parameter (new CCodeFormalParameter ("s2", "const " + st.get_cname () + "*")); + + // definition + var cblock = new CCodeBlock (); + + // if (s1 == s2) return TRUE; + { + var block = new CCodeBlock (); + block.add_statement (new CCodeReturnStatement (new CCodeConstant ("TRUE"))); + + var cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("s1"), new CCodeIdentifier ("s2")); + var cif = new CCodeIfStatement (cexp, block); + cblock.add_statement (cif); + } + // if (s1 == NULL || s2 == NULL) return FALSE; + { + var block = new CCodeBlock (); + block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE"))); + + var cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("s1"), new CCodeConstant ("NULL")); + var cif = new CCodeIfStatement (cexp, block); + cblock.add_statement (cif); + + cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("s2"), new CCodeConstant ("NULL")); + cif = new CCodeIfStatement (cexp, block); + cblock.add_statement (cif); + } + // return (*s1 == *s2); + { + var cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("s1")), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("s2"))); + cblock.add_statement (new CCodeReturnStatement (cexp)); + } + + // append to file + + source_declarations.add_type_member_declaration (function.copy ()); + + function.block = cblock; + source_type_member_definition.append (function); + + return equal_func; + } + private string generate_struct_dup_wrapper (ValueType value_type) { string dup_func = "_%sdup".printf (value_type.type_symbol.get_lower_case_cprefix ()); @@ -4335,8 +4391,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (expr.operator == BinaryOperator.EQUALITY || expr.operator == BinaryOperator.INEQUALITY) { - var left_type = expr.left.value_type; - var right_type = expr.right.value_type; + var left_type = expr.left.target_type; + var right_type = expr.right.target_type; make_comparable_cexpression (ref left_type, ref cleft, ref right_type, ref cright); if (left_type is StructValueType && right_type is StructValueType) { @@ -4346,6 +4402,14 @@ internal class Vala.CCodeBaseModule : CCodeModule { ccall.add_argument (cright); cleft = ccall; cright = new CCodeConstant ("TRUE"); + } else if ((left_type is IntegerType || left_type is FloatingType || left_type is BooleanType) && left_type.nullable && + (right_type is IntegerType || right_type is FloatingType || right_type is BooleanType) && right_type.nullable) { + var equalfunc = generate_numeric_equal_function ((Struct) left_type.data_type as Struct); + var ccall = new CCodeFunctionCall (new CCodeIdentifier (equalfunc)); + ccall.add_argument (cleft); + ccall.add_argument (cright); + cleft = ccall; + cright = new CCodeConstant ("TRUE"); } } diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index 27477239e..53dda1c82 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -323,6 +323,20 @@ 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.nullable != right.value_type.nullable) { + // if only one operand is nullable, make sure the other operand is promoted to nullable as well + if (!left.value_type.nullable) { + left.target_type.nullable = true; + } else if (!right.value_type.nullable) { + right.target_type.nullable = true; + } + } + if (left.value_type.compatible (analyzer.string_type) && right.value_type.compatible (analyzer.string_type)) { // string comparison