[vala/0.40] codegen: Improve array-dup-wrapper for empty arrays
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.40] codegen: Improve array-dup-wrapper for empty arrays
- Date: Mon, 22 Jun 2020 09:06:05 +0000 (UTC)
commit 73ffc76f090c6fc300a3bc44952a0c5a391cd869
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Sun May 24 19:25:41 2020 +0200
codegen: Improve array-dup-wrapper for empty arrays
Guard against negative lengths and consistently return NULL if allocated
size would be 0.
See https://gitlab.gnome.org/GNOME/vala/issues/999
codegen/valaccodearraymodule.vala | 18 ++++++++++++++
tests/Makefile.am | 1 +
tests/arrays/empty-length-0.vala | 52 +++++++++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index ee614340f..0a2d614f4 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -509,12 +509,20 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
gnew.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
CCodeExpression length_expr = new CCodeIdentifier ("length");
+ CCodeBinaryOperator length_check_op;
// add extra item to have array NULL-terminated for all reference types
if (array_type.element_type.data_type != null &&
array_type.element_type.data_type.is_reference_type ()) {
length_expr = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS,
length_expr, new CCodeConstant ("1"));
+ length_check_op = CCodeBinaryOperator.GREATER_THAN_OR_EQUAL;
+ } else {
+ length_check_op = CCodeBinaryOperator.GREATER_THAN;
}
gnew.add_argument (length_expr);
+ // only attempt to dup if length >=/> 0, this deals with negative lengths and returns
NULL
+ var length_check = new CCodeBinaryExpression (length_check_op, new CCodeIdentifier
("length"), new CCodeConstant ("0"));
+ ccode.open_if (length_check);
+
ccode.add_declaration (get_ccode_name (array_type), cvardecl);
ccode.add_assignment (new CCodeIdentifier ("result"), gnew);
@@ -528,7 +536,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
ccode.close ();
ccode.add_return (new CCodeIdentifier ("result"));
+
+ ccode.close ();
+ ccode.add_return (new CCodeIdentifier ("NULL"));
} else {
+ // only dup if length > 0, this deals with negative lengths and returns NULL
+ var length_check = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, new
CCodeIdentifier ("length"), new CCodeConstant ("0"));
+ ccode.open_if (length_check);
+
var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
dup_call.add_argument (new CCodeIdentifier ("self"));
@@ -537,6 +552,9 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new
CCodeIdentifier ("length"), sizeof_call));
ccode.add_return (dup_call);
+
+ ccode.close ();
+ ccode.add_return (new CCodeIdentifier ("NULL"));
}
// append to file
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f4badf3a7..b99bb6641 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -68,6 +68,7 @@ TESTS = \
arrays/cast-silent-invalid.test \
arrays/class-field-length-cname.vala \
arrays/constant-element-access.vala \
+ arrays/empty-length-0.vala \
arrays/expression-bracket.test \
arrays/fixed-length-init0-not-allowed.vala \
arrays/field-global-length-cname.vala \
diff --git a/tests/arrays/empty-length-0.vala b/tests/arrays/empty-length-0.vala
new file mode 100644
index 000000000..8d64f304a
--- /dev/null
+++ b/tests/arrays/empty-length-0.vala
@@ -0,0 +1,52 @@
+struct Manam {
+ string s;
+}
+
+string[] foo;
+int[] bar;
+Manam[] manam;
+
+string[] get_foo () {
+ return foo;
+}
+
+int[] get_bar () {
+ return bar;
+}
+
+Manam[] get_manam () {
+ return manam;
+}
+
+void main () {
+ {
+ foo = new string[0];
+ assert (foo != null);
+ assert (get_foo () != null);
+ }
+ {
+ foo = {};
+ assert (foo != null);
+ assert (get_foo () != null);
+ }
+ {
+ bar = new int[0];
+ //assert (bar != null);
+ assert (get_bar () == null);
+ }
+ {
+ bar = {};
+ //assert (bar != null);
+ assert (get_bar () == null);
+ }
+ {
+ manam = new Manam[0];
+ //assert (manam != null);
+ assert (get_manam () == null);
+ }
+ {
+ manam = {};
+ //assert (manam != null);
+ assert (get_manam () == null);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]