[vala/0.48] codegen: Improve array-dup-wrapper for empty arrays
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.48] codegen: Improve array-dup-wrapper for empty arrays
- Date: Mon, 22 Jun 2020 07:01:46 +0000 (UTC)
commit 186ee3dce8013d2f799f0efe326bb5b478a60974
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 | 2 ++
tests/arrays/empty-length-0.vala | 52 +++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 5fa9ea23d..0192f2cc9 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -541,9 +541,13 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
}
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.type_symbol != null &&
array_type.element_type.type_symbol.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);
@@ -553,6 +557,10 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
gnew.add_argument (csizeof);
}
+ // 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);
@@ -566,7 +574,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 sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name
(array_type.element_type)));
var length_expr = new CCodeIdentifier ("length");
@@ -597,6 +612,9 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
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 142bacea2..2a75719b9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -79,6 +79,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 \
@@ -948,6 +949,7 @@ LINUX_TESTS = \
POSIX_TESTS = \
basic-types/arrays.vala \
+ arrays/empty-length-0.vala \
structs/struct_only.vala \
delegates/delegate_only.vala \
enums/enum_only.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]