From: Juerg Billeter Date: Fri, 18 Jan 2008 16:51:06 +0000 (+0000) Subject: simplify conditional expression type analysis, fixes crash X-Git-Tag: VALA_0_1_6~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c580ce240710aba09f19cff75282d37d460c45ce;p=thirdparty%2Fvala.git simplify conditional expression type analysis, fixes crash 2008-01-18 Juerg Billeter * vala/valanulltype.vala, vala/valasemanticanalyzer.vala: simplify conditional expression type analysis, fixes crash svn path=/trunk/; revision=851 --- diff --git a/ChangeLog b/ChangeLog index cef312d80..bf7b3b13c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-01-18 Jürg Billeter + + * vala/valanulltype.vala, vala/valasemanticanalyzer.vala: simplify + conditional expression type analysis, fixes crash + 2008-01-18 Jürg Billeter * gobject/valaccodegeneratormethod.vala: fix methods with ref array diff --git a/vala/valanulltype.vala b/vala/valanulltype.vala index 4dcf18ce3..5221c5b4d 100644 --- a/vala/valanulltype.vala +++ b/vala/valanulltype.vala @@ -52,4 +52,8 @@ public class Vala.NullType : ReferenceType { /* null is not compatible with any other type (i.e. value types) */ return false; } + + public override DataType! copy () { + return new NullType (); + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 9bcf65b7c..988dd8652 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -2359,114 +2359,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { expr.static_type = bool_type; } - private DataType compute_common_base_type (Collection types, SourceReference source_reference) { - bool null_found = false; - bool class_or_iface_found = false; - bool type_param_found = false; - bool ref_struct_found = false; - bool val_struct_found = false; - bool enum_found = false; - bool callback_found = false; - DataType base_type = null; - DataType last_type = null; - foreach (DataType type in types) { - last_type = type; - if (type.error) { - return new InvalidType (); - } - if (type.data_type == null && type.type_parameter == null) { - if (!null_found) { - null_found = true; - if (val_struct_found || enum_found) { - base_type.error = true; - break; - } - } - } else if (type.data_type is Class || type.data_type is Interface) { - if (!class_or_iface_found) { - class_or_iface_found = true; - if (type_param_found || ref_struct_found || val_struct_found || enum_found || callback_found) { - base_type.error = true; - break; - } - } - } else if (type.type_parameter != null) { - if (!type_param_found) { - type_param_found = true; - if (class_or_iface_found || ref_struct_found || val_struct_found || enum_found || callback_found) { - base_type.error = true; - break; - } - } - } else if (type.data_type is Struct) { - var st = (Struct) type.data_type; - if (st.is_reference_type ()) { - if (!ref_struct_found) { - ref_struct_found = true; - if (class_or_iface_found || type_param_found || val_struct_found || enum_found || callback_found) { - base_type.error = true; - break; - } - } - } else { - if (!val_struct_found) { - val_struct_found = true; - if (class_or_iface_found || type_param_found || ref_struct_found || enum_found || callback_found) { - base_type.error = true; - break; - } - } - } - } else if (type.data_type is Enum) { - if (!enum_found) { - enum_found = true; - if (class_or_iface_found || type_param_found || ref_struct_found || val_struct_found) { - base_type.error = true; - break; - } - } - } else if (type.data_type is Delegate) { - if (!callback_found) { - callback_found = true; - if (class_or_iface_found || type_param_found || ref_struct_found || val_struct_found || enum_found) { - base_type.error = true; - break; - } - } - } else { - Report.error (type.source_reference, "internal error: unsupported type `%s'".printf (type.to_string ())); - return new InvalidType (); - } - if (base_type == null) { - base_type = new DataType (); - base_type.data_type = type.data_type; - base_type.type_parameter = type.type_parameter; - base_type.nullable = type.nullable; - base_type.is_null = type.is_null; - base_type.transfers_ownership = type.transfers_ownership; - } else { - if (base_type.data_type != type.data_type) { - if (type.compatible (base_type)) { - } else if (base_type.compatible (type)) { - base_type.data_type = type.data_type; - } else { - base_type.error = true; - break; - } - } - base_type.nullable = base_type.nullable || type.nullable; - base_type.is_null = base_type.is_null && type.is_null; - // if one subexpression transfers ownership, all subexpressions must transfer ownership - // FIXME add ref calls to subexpressions that don't transfer ownership - base_type.transfers_ownership = base_type.transfers_ownership || type.transfers_ownership; - } - } - if (base_type != null && base_type.error) { - Report.error (source_reference, "`%s' is incompatible with `%s'".printf (last_type.to_string (), base_type.to_string ())); - } - return base_type; - } - public override void visit_conditional_expression (ConditionalExpression! expr) { if (!expr.condition.static_type.compatible (bool_type)) { expr.error = true; @@ -2475,10 +2367,15 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } /* FIXME: support memory management */ - Gee.List types = new ArrayList (); - types.add (expr.true_expression.static_type); - types.add (expr.false_expression.static_type); - expr.static_type = compute_common_base_type (types, expr.source_reference); + if (expr.false_expression.static_type.compatible (expr.true_expression.static_type)) { + expr.static_type = expr.true_expression.static_type.copy (); + } else if (expr.true_expression.static_type.compatible (expr.false_expression.static_type)) { + expr.static_type = expr.false_expression.static_type.copy (); + } else { + expr.error = true; + Report.error (expr.condition.source_reference, "Incompatible expressions"); + return; + } } private string get_lambda_name () {