summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2023-01-31 15:43:57 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2023-01-31 15:43:57 +0100
commitc72958545735716f752a439cda183bf5c45333d5 (patch)
tree03752006d281794aa0ec0aefe9f7acf909b826b2
parent54ca3c304d252eda7fe7ee50014ca28a3b68dd19 (diff)
downloadvala-c72958545735716f752a439cda183bf5c45333d5.tar.gz
codegen: Perform required casts for generic types of return-values and in/out-parameters
Found by -Werror=int-conversion Fixes https://gitlab.gnome.org/GNOME/vala/issues/1407
-rw-r--r--codegen/valaccodebasemodule.vala4
-rw-r--r--codegen/valaccodemethodcallmodule.vala2
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/generics/method-return-cast.c-expected127
-rw-r--r--tests/generics/method-return-cast.vala35
-rw-r--r--tests/generics/parameter-in-cast.c-expected172
-rw-r--r--tests/generics/parameter-in-cast.vala42
-rw-r--r--tests/generics/parameter-out-cast.c-expected86
-rw-r--r--tests/generics/parameter-out-cast.vala21
9 files changed, 492 insertions, 0 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 5d765c314..cf72070eb 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4181,6 +4181,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
CCodeExpression result_lhs = get_cexpression ("result");
if (current_return_type.is_real_non_null_struct_type () && !is_in_coroutine ()) {
result_lhs = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result_lhs);
+ } else if (current_return_type is GenericType) {
+ set_cvalue (stmt.return_expression, convert_to_generic_pointer (get_cvalue (stmt.return_expression), stmt.return_expression.value_type));
}
ccode.add_assignment (result_lhs, get_cvalue (stmt.return_expression));
}
@@ -4341,6 +4343,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
set_cvalue (expr, convert_to_generic_pointer (get_cvalue (expr), expr.target_type));
((GLibValue) expr.target_value).lvalue = false;
}
+ } else if (expr.formal_target_type is GenericType && !(expr.value_type is GenericType)) {
+ set_cvalue (expr, convert_to_generic_pointer (get_cvalue (expr), expr.value_type));
}
// Allow null to initialize non-null struct inside initializer list
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 6332271ad..95087b535 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -509,6 +509,8 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
carg_map.set (get_param_pos (get_ccode_destroy_notify_pos (param)), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_delegate_target_destroy_notify (arg)));
}
}
+ } else if (param.variable_type is GenericType) {
+ set_cvalue (arg, convert_from_generic_pointer (get_cvalue (arg), arg.target_type));
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f8ddab919..518b892a9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -798,11 +798,14 @@ TESTS = \
generics/integer-type-cast.vala \
generics/integer-type-cast-return.vala \
generics/parameter-invalid-initializer.test \
+ generics/parameter-in-cast.vala \
+ generics/parameter-out-cast.vala \
generics/parameter-sizeof-initializer.vala \
generics/member-dup-destroy.vala \
generics/method-parameter-type-missing.test \
generics/method-parameter-unknown-type-parameter.test \
generics/method-parameter-unknown-type-parameter-2.test \
+ generics/method-return-cast.vala \
generics/method-return-type-missing.test \
generics/method-return-unknown-type-parameter.test \
generics/method-return-unknown-type-parameter-2.test \
diff --git a/tests/generics/method-return-cast.c-expected b/tests/generics/method-return-cast.c-expected
new file mode 100644
index 000000000..08e05f365
--- /dev/null
+++ b/tests/generics/method-return-cast.c-expected
@@ -0,0 +1,127 @@
+/* generics_method_return_cast.c generated by valac, the Vala compiler
+ * generated from generics_method_return_cast.vala, do not modify */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+VALA_EXTERN gboolean get_bool (void);
+VALA_EXTERN gpointer minim_b (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func);
+VALA_EXTERN guint32 get_uint32 (void);
+VALA_EXTERN gpointer minim_u (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func);
+VALA_EXTERN gchar* get_string (void);
+VALA_EXTERN gpointer minim_s (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func);
+static void _vala_main (void);
+
+gboolean
+get_bool (void)
+{
+ gboolean result;
+ result = TRUE;
+ return result;
+}
+
+gpointer
+minim_b (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func)
+{
+ gpointer result;
+ result = (gpointer) ((gintptr) get_bool ());
+ return result;
+}
+
+guint32
+get_uint32 (void)
+{
+ guint32 result;
+ result = (guint32) 42U;
+ return result;
+}
+
+gpointer
+minim_u (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func)
+{
+ gpointer result;
+ result = (gpointer) ((guintptr) get_uint32 ());
+ return result;
+}
+
+gchar*
+get_string (void)
+{
+ gchar* _tmp0_;
+ gchar* result;
+ _tmp0_ = g_strdup ("bar");
+ result = _tmp0_;
+ return result;
+}
+
+gpointer
+minim_s (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func)
+{
+ gchar* _tmp0_;
+ gpointer result;
+ _tmp0_ = get_string ();
+ result = _tmp0_;
+ return result;
+}
+
+static void
+_vala_main (void)
+{
+ {
+ gpointer _tmp0_;
+ _tmp0_ = minim_b (G_TYPE_BOOLEAN, NULL, NULL);
+ _vala_assert (((gboolean) ((gintptr) _tmp0_)) == TRUE, "minim_b<bool> () == true");
+ }
+ {
+ gpointer _tmp1_;
+ _tmp1_ = minim_u (G_TYPE_UINT, NULL, NULL);
+ _vala_assert (((guint32) ((guintptr) _tmp1_)) == ((guint32) 42U), "minim_u<uint32> () == 42U");
+ }
+ {
+ gpointer _tmp2_;
+ gchar* _tmp3_;
+ _tmp2_ = minim_s (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free);
+ _tmp3_ = (gchar*) _tmp2_;
+ _vala_assert (g_strcmp0 (_tmp3_, "bar") == 0, "minim_s<string> () == \"bar\"");
+ _g_free0 (_tmp3_);
+ }
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
diff --git a/tests/generics/method-return-cast.vala b/tests/generics/method-return-cast.vala
new file mode 100644
index 000000000..ae3bc8def
--- /dev/null
+++ b/tests/generics/method-return-cast.vala
@@ -0,0 +1,35 @@
+bool get_bool () {
+ return true;
+}
+
+T minim_b<T> () {
+ return get_bool ();
+}
+
+uint32 get_uint32 () {
+ return 42U;
+}
+
+T minim_u<T> () {
+ return get_uint32 ();
+}
+
+string get_string () {
+ return "bar";
+}
+
+T minim_s<T> () {
+ return get_string ();
+}
+
+void main () {
+ {
+ assert (minim_b<bool> () == true);
+ }
+ {
+ assert (minim_u<uint32> () == 42U);
+ }
+ {
+ assert (minim_s<string> () == "bar");
+ }
+}
diff --git a/tests/generics/parameter-in-cast.c-expected b/tests/generics/parameter-in-cast.c-expected
new file mode 100644
index 000000000..2c70aaed6
--- /dev/null
+++ b/tests/generics/parameter-in-cast.c-expected
@@ -0,0 +1,172 @@
+/* generics_parameter_in_cast.c generated by valac, the Vala compiler
+ * generated from generics_parameter_in_cast.vala, do not modify */
+
+#include <glib-object.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+VALA_EXTERN gpointer manam (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func,
+ gconstpointer foo);
+VALA_EXTERN gboolean get_bool (void);
+VALA_EXTERN gpointer minim_b (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func);
+VALA_EXTERN guint32 get_uint32 (void);
+VALA_EXTERN gpointer minim_u (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func);
+VALA_EXTERN gchar* get_string (void);
+VALA_EXTERN gpointer minim_s (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func);
+static void _vala_main (void);
+
+gpointer
+manam (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func,
+ gconstpointer foo)
+{
+ gpointer _tmp0_;
+ gpointer result;
+ _tmp0_ = ((foo != NULL) && (t_dup_func != NULL)) ? t_dup_func ((gpointer) foo) : ((gpointer) foo);
+ result = _tmp0_;
+ return result;
+}
+
+gboolean
+get_bool (void)
+{
+ gboolean result;
+ result = TRUE;
+ return result;
+}
+
+gpointer
+minim_b (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func)
+{
+ gpointer _tmp0_;
+ gpointer result;
+ _tmp0_ = manam (t_type, (GBoxedCopyFunc) t_dup_func, (GDestroyNotify) t_destroy_func, (gpointer) ((gintptr) get_bool ()));
+ result = _tmp0_;
+ return result;
+}
+
+guint32
+get_uint32 (void)
+{
+ guint32 result;
+ result = (guint32) 23U;
+ return result;
+}
+
+gpointer
+minim_u (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func)
+{
+ gpointer _tmp0_;
+ gpointer result;
+ _tmp0_ = manam (t_type, (GBoxedCopyFunc) t_dup_func, (GDestroyNotify) t_destroy_func, (gpointer) ((guintptr) get_uint32 ()));
+ result = _tmp0_;
+ return result;
+}
+
+gchar*
+get_string (void)
+{
+ gchar* _tmp0_;
+ gchar* result;
+ _tmp0_ = g_strdup ("bar");
+ result = _tmp0_;
+ return result;
+}
+
+gpointer
+minim_s (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func)
+{
+ gchar* _tmp0_;
+ gchar* _tmp1_;
+ gpointer _tmp2_;
+ gpointer _tmp3_;
+ gpointer result;
+ _tmp0_ = get_string ();
+ _tmp1_ = _tmp0_;
+ _tmp2_ = manam (t_type, (GBoxedCopyFunc) t_dup_func, (GDestroyNotify) t_destroy_func, _tmp1_);
+ _tmp3_ = _tmp2_;
+ _g_free0 (_tmp1_);
+ result = _tmp3_;
+ return result;
+}
+
+static void
+_vala_main (void)
+{
+ {
+ gpointer _tmp0_;
+ gpointer _tmp1_;
+ _tmp0_ = manam (G_TYPE_BOOLEAN, NULL, NULL, (gpointer) ((gintptr) get_bool ()));
+ _vala_assert (((gboolean) ((gintptr) _tmp0_)) == TRUE, "manam<bool> (get_bool ()) == true");
+ _tmp1_ = minim_b (G_TYPE_BOOLEAN, NULL, NULL);
+ _vala_assert (((gboolean) ((gintptr) _tmp1_)) == TRUE, "minim_b<bool> () == true");
+ }
+ {
+ gpointer _tmp2_;
+ gpointer _tmp3_;
+ _tmp2_ = manam (G_TYPE_UINT, NULL, NULL, (gpointer) ((guintptr) get_uint32 ()));
+ _vala_assert (((guint32) ((guintptr) _tmp2_)) == ((guint32) 23U), "manam<uint32> (get_uint32 ()) == 23U");
+ _tmp3_ = minim_u (G_TYPE_UINT, NULL, NULL);
+ _vala_assert (((guint32) ((guintptr) _tmp3_)) == ((guint32) 23U), "minim_u<uint32> () == 23U");
+ }
+ {
+ gchar* _tmp4_;
+ gchar* _tmp5_;
+ gpointer _tmp6_;
+ gchar* _tmp7_;
+ gpointer _tmp8_;
+ gchar* _tmp9_;
+ _tmp4_ = get_string ();
+ _tmp5_ = _tmp4_;
+ _tmp6_ = manam (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, _tmp5_);
+ _tmp7_ = (gchar*) _tmp6_;
+ _vala_assert (g_strcmp0 (_tmp7_, "bar") == 0, "manam<string> (get_string ()) == \"bar\"");
+ _g_free0 (_tmp7_);
+ _g_free0 (_tmp5_);
+ _tmp8_ = minim_s (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free);
+ _tmp9_ = (gchar*) _tmp8_;
+ _vala_assert (g_strcmp0 (_tmp9_, "bar") == 0, "minim_s<string> () == \"bar\"");
+ _g_free0 (_tmp9_);
+ }
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
diff --git a/tests/generics/parameter-in-cast.vala b/tests/generics/parameter-in-cast.vala
new file mode 100644
index 000000000..270b7440f
--- /dev/null
+++ b/tests/generics/parameter-in-cast.vala
@@ -0,0 +1,42 @@
+T manam<T> (T foo) {
+ return foo;
+}
+
+bool get_bool () {
+ return true;
+}
+
+T minim_b<T> () {
+ return manam<T> (get_bool ());
+}
+
+uint32 get_uint32 () {
+ return 23U;
+}
+
+T minim_u<T> () {
+ return manam<T> (get_uint32 ());
+}
+
+string get_string () {
+ return "bar";
+}
+
+T minim_s<T> () {
+ return manam<T> (get_string ());
+}
+
+void main () {
+ {
+ assert (manam<bool> (get_bool ()) == true);
+ assert (minim_b<bool> () == true);
+ }
+ {
+ assert (manam<uint32> (get_uint32 ()) == 23U);
+ assert (minim_u<uint32> () == 23U);
+ }
+ {
+ assert (manam<string> (get_string ()) == "bar");
+ assert (minim_s<string> () == "bar");
+ }
+}
diff --git a/tests/generics/parameter-out-cast.c-expected b/tests/generics/parameter-out-cast.c-expected
new file mode 100644
index 000000000..a14f17524
--- /dev/null
+++ b/tests/generics/parameter-out-cast.c-expected
@@ -0,0 +1,86 @@
+/* generics_parameter_out_cast.c generated by valac, the Vala compiler
+ * generated from generics_parameter_out_cast.vala, do not modify */
+
+#include <glib-object.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+VALA_EXTERN void manam (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func,
+ gconstpointer foo,
+ gpointer* bar);
+static void _vala_main (void);
+
+void
+manam (GType t_type,
+ GBoxedCopyFunc t_dup_func,
+ GDestroyNotify t_destroy_func,
+ gconstpointer foo,
+ gpointer* bar)
+{
+ gpointer _vala_bar = NULL;
+ gpointer _tmp0_;
+ _tmp0_ = ((foo != NULL) && (t_dup_func != NULL)) ? t_dup_func ((gpointer) foo) : ((gpointer) foo);
+ ((_vala_bar == NULL) || (t_destroy_func == NULL)) ? NULL : (_vala_bar = (t_destroy_func (_vala_bar), NULL));
+ _vala_bar = _tmp0_;
+ if (bar) {
+ *bar = _vala_bar;
+ } else {
+ ((_vala_bar == NULL) || (t_destroy_func == NULL)) ? NULL : (_vala_bar = (t_destroy_func (_vala_bar), NULL));
+ }
+}
+
+static void
+_vala_main (void)
+{
+ {
+ gboolean bar = FALSE;
+ gpointer _tmp0_ = NULL;
+ manam (G_TYPE_BOOLEAN, NULL, NULL, (gpointer) ((gintptr) TRUE), &_tmp0_);
+ bar = (gboolean) ((gintptr) _tmp0_);
+ _vala_assert (bar == TRUE, "bar == true");
+ }
+ {
+ guint32 bar = 0U;
+ gpointer _tmp1_ = NULL;
+ manam (G_TYPE_UINT, NULL, NULL, (gpointer) ((guintptr) 23U), &_tmp1_);
+ bar = (guint32) ((guintptr) _tmp1_);
+ _vala_assert (bar == ((guint32) 23U), "bar == 23U");
+ }
+ {
+ gchar* bar = NULL;
+ gpointer _tmp2_ = NULL;
+ manam (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, "bar", &_tmp2_);
+ _g_free0 (bar);
+ bar = (gchar*) _tmp2_;
+ _vala_assert (g_strcmp0 (bar, "bar") == 0, "bar == \"bar\"");
+ _g_free0 (bar);
+ }
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
diff --git a/tests/generics/parameter-out-cast.vala b/tests/generics/parameter-out-cast.vala
new file mode 100644
index 000000000..110ffc95e
--- /dev/null
+++ b/tests/generics/parameter-out-cast.vala
@@ -0,0 +1,21 @@
+void manam<T> (T foo, out T bar) {
+ bar = foo;
+}
+
+void main () {
+ {
+ bool bar;
+ manam<bool> (true, out bar);
+ assert (bar == true);
+ }
+ {
+ uint32 bar;
+ manam<uint32> (23U, out bar);
+ assert (bar == 23U);
+ }
+ {
+ string bar;
+ manam<string> ("bar", out bar);
+ assert (bar == "bar");
+ }
+}