]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Don't allow casting real structs to classes or simple-types
authorYotam Nachum <me@yotam.net>
Sat, 6 Nov 2021 17:05:13 +0000 (19:05 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Fri, 12 Nov 2021 14:32:08 +0000 (15:32 +0100)
This led to C compiler errors or obvious runtimes failures.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/1249

tests/Makefile.am
tests/structs/cast-struct-to-class.test [new file with mode: 0644]
tests/structs/cast-struct-to-simple-struct.test [new file with mode: 0644]
vala/valacastexpression.vala

index 9a6c4b3f2d7225c827aac2993fb16a1d256fc38e..ad65913ce263375cc237874cd34907320c142fbc 100644 (file)
@@ -345,6 +345,8 @@ TESTS = \
        enums/bug763831.vala \
        enums/bug780050.vala \
        structs/cast-struct-boxed.vala \
+       structs/cast-struct-to-class.test \
+       structs/cast-struct-to-simple-struct.test \
        structs/struct_only.vala \
        structs/struct-base-types.vala \
        structs/struct-boxed-cast.vala \
diff --git a/tests/structs/cast-struct-to-class.test b/tests/structs/cast-struct-to-class.test
new file mode 100644 (file)
index 0000000..c87931e
--- /dev/null
@@ -0,0 +1,10 @@
+Invalid Code
+
+struct Foo {
+       public int i;
+}
+
+void main () {
+       Foo foo = { 42 };
+       Object bar = (Object) foo;
+}
diff --git a/tests/structs/cast-struct-to-simple-struct.test b/tests/structs/cast-struct-to-simple-struct.test
new file mode 100644 (file)
index 0000000..3cb6681
--- /dev/null
@@ -0,0 +1,10 @@
+Invalid Code
+
+struct Foo {
+       public int i;
+}
+
+void main () {
+       Foo foo = { 42 };
+       int bar = (int) foo;
+}
index 732b99a716d8c2e9e6df593c8e0b357d98719d0e..5d0783e41d95a4bf8568a510226d0fa769d0b503 100644 (file)
@@ -170,6 +170,15 @@ public class Vala.CastExpression : Expression {
                        return false;
                }
 
+               // Allow casting to array or pointer type
+               if (!(type_reference is ArrayType || type_reference is PointerType)) {
+                       if (!type_reference.is_real_struct_type () && inner.value_type.is_real_struct_type ()
+                           && (context.profile != Profile.GOBJECT || !(is_gvariant (context, inner.value_type) || is_gvalue (context, inner.value_type)))) {
+                               error = true;
+                               Report.error (source_reference, "Casting of struct `%s' to `%s' is not allowed", inner.value_type.to_qualified_string (), type_reference.to_qualified_string ());
+                       }
+               }
+
                if (type_reference is DelegateType && inner.value_type is MethodType) {
                        if (target_type != null) {
                                inner.value_type.value_owned = target_type.value_owned;