[vala/0.40] codegen: Real structs are allowed by simple generics and passed as reference
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.40] codegen: Real structs are allowed by simple generics and passed as reference
- Date: Mon, 5 Aug 2019 11:40:11 +0000 (UTC)
commit 4f7c841ec72dd2c1226012e9caba770acc50a384
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Mon Jul 8 19:11:19 2019 +0200
codegen: Real structs are allowed by simple generics and passed as reference
Add the required pointer-indirections to fix invalid memory accesses.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/819
codegen/valaccodemethodcallmodule.vala | 10 +++++++++
tests/Makefile.am | 1 +
tests/methods/varargs-gvalue.vala | 10 +++++++++
tests/methods/varargs-struct.vala | 40 ++++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 37716c9b7..d8eabffd0 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -268,6 +268,10 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
// generic method
int type_param_index = 0;
foreach (var type_arg in ma.get_type_arguments ()) {
+ // real structs are passed by reference for simple generics
+ if (get_ccode_simple_generics (m) && type_arg.is_real_struct_type ()
&& !type_arg.nullable && !(type_arg is PointerType)) {
+ type_arg = new PointerType (type_arg);
+ }
in_arg_map.set (get_param_pos (get_ccode_generic_type_pos (m) + 0.01
* type_param_index), new CCodeIdentifier (get_ccode_name (type_arg)));
type_param_index++;
}
@@ -765,6 +769,12 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
}
+ // real structs are passed by reference for simple generics
+ if (m != null && get_ccode_simple_generics (m) && m.return_type is GenericType
+ && expr.value_type.is_real_struct_type () && !expr.value_type.nullable &&
!(expr.value_type is PointerType)) {
+ ccall_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new
CCodeParenthesizedExpression (ccall_expr));
+ }
+
if (m != null && get_ccode_type (m) != null && get_ccode_type (m) != get_ccode_name
(m.return_type)) {
// Bug 699956: Implement cast for method return type if [CCode type=] annotation is
specified
ccall_expr = new CCodeCastExpression (ccall_expr, get_ccode_name (m.return_type));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2860cc213..6ca023f0b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -138,6 +138,7 @@ TESTS = \
methods/printf-constructor-invalid.test \
methods/varargs-gvalue.vala \
methods/varargs-out.vala \
+ methods/varargs-struct.vala \
control-flow/assigned-local-variable.vala \
control-flow/break.vala \
control-flow/break-invalid.test \
diff --git a/tests/methods/varargs-gvalue.vala b/tests/methods/varargs-gvalue.vala
index 3160b2356..25388207f 100644
--- a/tests/methods/varargs-gvalue.vala
+++ b/tests/methods/varargs-gvalue.vala
@@ -7,9 +7,19 @@ void foo (int first_arg, ...) {
assert (val.get_string () == "foo");
}
+void faz (int first_arg, ...) {
+ var args = va_list ();
+ Value* val = args.arg ();
+
+ assert (first_arg == 23);
+ assert (val.holds (typeof (string)));
+ assert (val.get_string () == "foo");
+}
+
void main () {
Value val = Value (typeof (string));
val.set_string ("foo");
foo (42, val);
+ faz (23, val);
}
diff --git a/tests/methods/varargs-struct.vala b/tests/methods/varargs-struct.vala
new file mode 100644
index 000000000..29ab4ec49
--- /dev/null
+++ b/tests/methods/varargs-struct.vala
@@ -0,0 +1,40 @@
+[CCode (has_type_id = false)]
+struct Bar {
+ public int i;
+ public int j;
+}
+
+void foo (int first_arg, ...) {
+ var args = va_list ();
+ Bar bar = args.arg ();
+
+ assert (first_arg == 42);
+ assert (bar.i == 23);
+ assert (bar.j == 4711);
+}
+
+void faz (int first_arg, ...) {
+ var args = va_list ();
+ Bar* bar = args.arg ();
+
+ assert (first_arg == 23);
+ assert (bar.i == 23);
+ assert (bar.j == 4711);
+}
+
+void fab (int first_arg, ...) {
+ var args = va_list ();
+ Bar? bar = args.arg ();
+
+ assert (first_arg == 65);
+ assert (bar.i == 23);
+ assert (bar.j == 4711);
+}
+
+void main () {
+ Bar bar = {23, 4711};
+
+ foo (42, bar);
+ faz (23, bar);
+ fab (65, bar);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]