diff options
-rw-r--r-- | codegen/valaccodebasemodule.vala | 4 | ||||
-rw-r--r-- | codegen/valaccodemethodcallmodule.vala | 2 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/generics/method-return-cast.c-expected | 127 | ||||
-rw-r--r-- | tests/generics/method-return-cast.vala | 35 | ||||
-rw-r--r-- | tests/generics/parameter-in-cast.c-expected | 172 | ||||
-rw-r--r-- | tests/generics/parameter-in-cast.vala | 42 | ||||
-rw-r--r-- | tests/generics/parameter-out-cast.c-expected | 86 | ||||
-rw-r--r-- | tests/generics/parameter-out-cast.vala | 21 |
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"); + } +} |