]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Let methods return -1 on error by default if possible
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 5 Jul 2018 06:17:32 +0000 (08:17 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 5 Jul 2018 10:42:00 +0000 (12:42 +0200)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/526

codegen/valaccode.vala
codegen/valaccodeattribute.vala
codegen/valaccodebasemodule.vala
codegen/valagerrormodule.vala
tests/Makefile.am
tests/errors/bug762377.vala [new file with mode: 0644]
vala/valausedattr.vala
vapi/glib-2.0.vapi

index 82b4699e7d7495fdaa8761d15f7a506075861949..1bb92171ea1b331dfbbec88ccfa7d5c8b26cc047 100644 (file)
@@ -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);
        }
index f6b1e4c3df268887d98ec269a27914380e5119b9..fc22c3e72305bc052881ec097897e0d2193b38a3 100644 (file)
@@ -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;
index 71d5d5ae67b6779971fe3bae17a67af1c42af72b..67aac9efb1b08480bdde39f0334b9d0386cd13d9 100644 (file)
@@ -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));
                }
        }
 
index add71ce6951ea1e3659b143aa118e9ca7c31210b..ea8367fd361a924f6f006287f5bd8d610af3f7c6 100644 (file)
@@ -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);
                }
        }
 
index 9f9d614b3187382715a4f2f095706f50be4f3b1d..879f606eae143dfbcdf77cf9ce71f56b99e0ca15 100644 (file)
@@ -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 (file)
index 0000000..f5b2fb9
--- /dev/null
@@ -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) {
+       }
+}
index 999cfc8675583151814b11573db3eba2d4ac76c9..78fdd0871e95311042419950390c55ec7a4dd14b 100644 (file)
@@ -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", "",
index 7c4d5e528ceb5c81ebc5959837341952dabc6be4..d8ad214f26d35185a053ff77ad3c60a5bba211f7 100644 (file)
@@ -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")]