From: Rico Tzschichholz Date: Thu, 5 Jul 2018 06:17:32 +0000 (+0200) Subject: codegen: Let methods return -1 on error by default if possible X-Git-Tag: 0.41.90~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03d4222d92195700bb58bbb1ca26c9234017ffbe;p=thirdparty%2Fvala.git codegen: Let methods return -1 on error by default if possible Fixes https://gitlab.gnome.org/GNOME/vala/issues/526 --- diff --git a/codegen/valaccode.vala b/codegen/valaccode.vala index 82b4699e7..1bb92171e 100644 --- a/codegen/valaccode.vala +++ b/codegen/valaccode.vala @@ -222,6 +222,10 @@ namespace Vala { return get_ccode_attribute(sym).default_value; } + public static string get_ccode_default_value_on_error (TypeSymbol sym) { + return get_ccode_attribute (sym).default_value_on_error; + } + public static bool get_ccode_has_copy_function (Struct st) { return st.get_attribute_bool ("CCode", "has_copy_function", true); } diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index f6b1e4c3d..fc22c3e72 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -397,6 +397,20 @@ public class Vala.CCodeAttribute : AttributeCache { } } + public string default_value_on_error { + get { + if (_default_value_on_error == null) { + if (ccode != null) { + _default_value_on_error = ccode.get_string ("default_value_on_error"); + } + if (_default_value_on_error == null) { + _default_value_on_error = default_value; + } + } + return _default_value_on_error; + } + } + public double pos { get { if (_pos == null) { @@ -586,6 +600,7 @@ public class Vala.CCodeAttribute : AttributeCache { private string _take_value_function; private string _param_spec_function; private string _default_value; + private string _default_value_on_error; private double? _pos; private string _vfunc_name; private string _finish_name; diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 71d5d5ae6..67aac9efb 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -3576,7 +3576,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { temp_ref_values.clear (); } - public void emit_temp_var (LocalVariable local) { + public void emit_temp_var (LocalVariable local, bool on_error = false) { var init = (!local.name.has_prefix ("*") && local.init); if (is_in_coroutine ()) { closure_struct.add_field (get_ccode_name (local.variable_type), local.name); @@ -3585,7 +3585,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // as they might be used multiple times when declared in a loop if (init) { - var initializer = default_value_for_type (local.variable_type, false); + var initializer = default_value_for_type (local.variable_type, false, on_error); if (initializer == null) { cfile.add_include ("string.h"); var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset")); @@ -3600,7 +3600,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } else { var cvar = new CCodeVariableDeclarator (local.name, null, get_ccode_declarator_suffix (local.variable_type)); if (init) { - cvar.initializer = default_value_for_type (local.variable_type, true); + cvar.initializer = default_value_for_type (local.variable_type, true, on_error); cvar.init0 = true; } ccode.add_declaration (get_ccode_name (local.variable_type), cvar); @@ -6224,11 +6224,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { return type; } - public CCodeExpression? default_value_for_type (DataType type, bool initializer_expression) { + public CCodeExpression? default_value_for_type (DataType type, bool initializer_expression, bool on_error = false) { var st = type.data_type as Struct; var array_type = type as ArrayType; - if (type.data_type != null && !type.nullable && get_ccode_default_value (type.data_type) != "") { - return new CCodeConstant (get_ccode_default_value (type.data_type)); + if (type.data_type != null && !type.nullable + && (on_error ? get_ccode_default_value_on_error (type.data_type) : get_ccode_default_value (type.data_type)) != "") { + return new CCodeConstant (on_error ? get_ccode_default_value_on_error (type.data_type) : get_ccode_default_value (type.data_type)); } else if (initializer_expression && !type.nullable && (st != null || (array_type != null && array_type.fixed_length))) { // 0-initialize struct with struct initializer { 0 } @@ -6424,16 +6425,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { cfile.add_function (function); } - public void return_default_value (DataType return_type) { + public void return_default_value (DataType return_type, bool on_error = false) { var st = return_type.data_type as Struct; if (st != null && st.is_simple_type () && !return_type.nullable) { // 0-initialize struct with struct initializer { 0 } // only allowed as initializer expression in C var ret_temp_var = get_temp_variable (return_type, true, null, true); - emit_temp_var (ret_temp_var); + emit_temp_var (ret_temp_var, on_error); ccode.add_return (new CCodeIdentifier (ret_temp_var.name)); } else { - ccode.add_return (default_value_for_type (return_type, false)); + ccode.add_return (default_value_for_type (return_type, false, on_error)); } } diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala index add71ce69..ea8367fd3 100644 --- a/codegen/valagerrormodule.vala +++ b/codegen/valagerrormodule.vala @@ -109,7 +109,7 @@ public class Vala.GErrorModule : CCodeDelegateModule { } else if (is_in_coroutine ()) { ccode.add_return (new CCodeConstant ("FALSE")); } else { - return_default_value (current_return_type); + return_default_value (current_return_type, true); } } @@ -149,7 +149,7 @@ public class Vala.GErrorModule : CCodeDelegateModule { ccode.add_expression (unref); ccode.add_return (new CCodeConstant ("FALSE")); } else if (current_return_type != null) { - return_default_value (current_return_type); + return_default_value (current_return_type, true); } } diff --git a/tests/Makefile.am b/tests/Makefile.am index 9f9d614b3..879f606ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -327,6 +327,7 @@ TESTS = \ errors/bug623049.vala \ errors/bug639589.vala \ errors/bug651145.vala \ + errors/bug762377.vala \ errors/bug778224.vala \ asynchronous/bug595735.vala \ asynchronous/bug595755.vala \ diff --git a/tests/errors/bug762377.vala b/tests/errors/bug762377.vala new file mode 100644 index 000000000..f5b2fb959 --- /dev/null +++ b/tests/errors/bug762377.vala @@ -0,0 +1,18 @@ +class FooOutputStream : GLib.OutputStream { + public override ssize_t write (uint8[] buffer, Cancellable? cancellable = null) throws IOError { + throw new IOError.FAILED (""); + } + + public override bool close (Cancellable? cancellable = null) throws IOError { + return true; + } +} + +void main () { + try { + var output = new FooOutputStream (); + size_t bytes_written; + output.write_all ("Hello world!".data, out bytes_written); + } catch (IOError e) { + } +} diff --git a/vala/valausedattr.vala b/vala/valausedattr.vala index 999cfc867..78fdd0871 100644 --- a/vala/valausedattr.vala +++ b/vala/valausedattr.vala @@ -40,7 +40,7 @@ public class Vala.UsedAttr : CodeVisitor { "array_length_type", "array_length", "array_length_cname", "array_length_cexpr", "array_null_terminated", "vfunc_name", "finish_vfunc_name", "finish_name", "free_function_address_of", "pos", "delegate_target", "delegate_target_cname", "array_length_pos", "delegate_target_pos", "destroy_notify_pos", "ctype", "has_new_function", "notify", "finish_instance", - "use_inplace", "feature_test_macro", "", + "use_inplace", "feature_test_macro", "default_value_on_error", "", "Immutable", "", "Compact", "", diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index 7c4d5e528..d8ad214f2 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -111,7 +111,7 @@ public struct uchar { [SimpleType] [GIR (name = "gint")] -[CCode (cname = "gint", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", type_signature = "i")] +[CCode (cname = "gint", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", default_value_on_error = "-1", type_signature = "i")] [IntegerType (rank = 6)] public struct int { [CCode (cname = "G_MININT")] @@ -189,7 +189,7 @@ public struct uint { [SimpleType] [GIR (name = "gshort")] -[CCode (cname = "gshort", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", type_signature = "n")] +[CCode (cname = "gshort", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", default_value_on_error = "-1", type_signature = "n")] [IntegerType (rank = 4, min = -32768, max = 32767)] public struct short { [CCode (cname = "G_MINSHORT")] @@ -233,7 +233,7 @@ public struct ushort { [SimpleType] [GIR (name = "glong")] -[CCode (cname = "glong", cheader_filename = "glib.h", type_id = "G_TYPE_LONG", marshaller_type_name = "LONG", get_value_function = "g_value_get_long", set_value_function = "g_value_set_long", default_value = "0L")] +[CCode (cname = "glong", cheader_filename = "glib.h", type_id = "G_TYPE_LONG", marshaller_type_name = "LONG", get_value_function = "g_value_get_long", set_value_function = "g_value_set_long", default_value = "0L", default_value_on_error = "-1L")] [IntegerType (rank = 8)] public struct long { [CCode (cname = "G_MINLONG")] @@ -334,7 +334,7 @@ public struct size_t { [SimpleType] [GIR (name = "glong")] -[CCode (cname = "gssize", cheader_filename = "glib.h", type_id = "G_TYPE_LONG", marshaller_type_name = "LONG", get_value_function = "g_value_get_long", set_value_function = "g_value_set_long", default_value = "0L")] +[CCode (cname = "gssize", cheader_filename = "glib.h", type_id = "G_TYPE_LONG", marshaller_type_name = "LONG", get_value_function = "g_value_get_long", set_value_function = "g_value_set_long", default_value = "0L", default_value_on_error = "-1L")] [IntegerType (rank = 8)] public struct ssize_t { [Version (since = "2.14")] @@ -420,7 +420,7 @@ public struct intptr { [SimpleType] [GIR (name = "gint8")] -[CCode (cname = "gint8", cheader_filename = "glib.h", type_id = "G_TYPE_CHAR", marshaller_type_name = "CHAR", get_value_function = "g_value_get_char", set_value_function = "g_value_set_char", default_value = "0", type_signature = "y")] +[CCode (cname = "gint8", cheader_filename = "glib.h", type_id = "G_TYPE_CHAR", marshaller_type_name = "CHAR", get_value_function = "g_value_get_char", set_value_function = "g_value_set_char", default_value = "0", default_value_on_error = "-1", type_signature = "y")] [IntegerType (rank = 1, min = -128, max = 127)] public struct int8 { [Version (since = "2.4")] @@ -465,7 +465,7 @@ public struct uint8 { [SimpleType] [GIR (name = "gint16")] -[CCode (cname = "gint16", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", type_signature = "n")] +[CCode (cname = "gint16", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", default_value_on_error = "-1", type_signature = "n")] [IntegerType (rank = 4, min = -32768, max = 32767)] public struct int16 { [Version (since = "2.4")] @@ -553,7 +553,7 @@ public struct uint16 { [SimpleType] [GIR (name = "gint32")] -[CCode (cname = "gint32", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", type_signature = "i")] +[CCode (cname = "gint32", cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT", get_value_function = "g_value_get_int", set_value_function = "g_value_set_int", default_value = "0", default_value_on_error = "-1", type_signature = "i")] [IntegerType (rank = 6)] public struct int32 { [Version (since = "2.4")] @@ -641,7 +641,7 @@ public struct uint32 { [SimpleType] [GIR (name = "gint64")] -[CCode (cname = "gint64", cheader_filename = "glib.h", type_id = "G_TYPE_INT64", marshaller_type_name = "INT64", get_value_function = "g_value_get_int64", set_value_function = "g_value_set_int64", default_value = "0LL", type_signature = "x")] +[CCode (cname = "gint64", cheader_filename = "glib.h", type_id = "G_TYPE_INT64", marshaller_type_name = "INT64", get_value_function = "g_value_get_int64", set_value_function = "g_value_set_int64", default_value = "0LL", default_value_on_error = "-1LL", type_signature = "x")] [IntegerType (rank = 10)] public struct int64 { [CCode (cname = "G_MININT64")] @@ -766,7 +766,7 @@ public struct uint64 { [SimpleType] [GIR (name = "gfloat")] -[CCode (cname = "gfloat", cheader_filename = "glib.h,float.h,math.h", type_id = "G_TYPE_FLOAT", marshaller_type_name = "FLOAT", get_value_function = "g_value_get_float", set_value_function = "g_value_set_float", default_value = "0.0F")] +[CCode (cname = "gfloat", cheader_filename = "glib.h,float.h,math.h", type_id = "G_TYPE_FLOAT", marshaller_type_name = "FLOAT", get_value_function = "g_value_get_float", set_value_function = "g_value_set_float", default_value = "0.0F", default_value_on_error = "-1.0F")] [FloatingType (rank = 1)] public struct float { [CCode (cname = "FLT_ROUNDS")] @@ -824,7 +824,7 @@ public struct float { [SimpleType] [GIR (name = "gdouble")] -[CCode (cname = "gdouble", cheader_filename = "glib.h,float.h,math.h", type_id = "G_TYPE_DOUBLE", marshaller_type_name = "DOUBLE", get_value_function = "g_value_get_double", set_value_function = "g_value_set_double", default_value = "0.0", type_signature = "d")] +[CCode (cname = "gdouble", cheader_filename = "glib.h,float.h,math.h", type_id = "G_TYPE_DOUBLE", marshaller_type_name = "DOUBLE", get_value_function = "g_value_get_double", set_value_function = "g_value_set_double", default_value = "0.0", default_value_on_error = "-1.0", type_signature = "d")] [FloatingType (rank = 2)] public struct double { [CCode (cname = "DBL_MANT_DIG")]