]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Don't pass a pointer to sizeof() if is not intended
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 22 Mar 2021 07:33:16 +0000 (08:33 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 1 Dec 2021 20:22:31 +0000 (21:22 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/442

codegen/valaccode.vala
codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/objects/bug728274.vala [new file with mode: 0644]

index 9b1da33f757a35dcfa3e862d0e87e6e441062069..6663364c2ee56ce339aa4ab8a323fd0cb65889d5 100644 (file)
@@ -45,6 +45,25 @@ namespace Vala {
                return get_ccode_attribute(node).const_name;
        }
 
+       public static string get_ccode_struct_name (CodeNode node) {
+               unowned DataType? data_type = node as DataType;
+
+               if (data_type is ObjectType) {
+                       return get_ccode_name (data_type.type_symbol);
+               } else if (data_type is ValueType && !data_type.nullable) {
+                       return get_ccode_name (data_type.type_symbol);
+               } else if (data_type is ClassType || data_type is InterfaceType) {
+                       return get_ccode_type_name ((ObjectTypeSymbol) data_type.type_symbol);
+               } else if (data_type is ErrorType) {
+                       return "GError";
+               } else if (node is CType) {
+                       return ((CType) node).ctype_name;
+               }
+
+               Report.error (node.source_reference, "internal: No type available");
+               return "";
+       }
+
        public static string get_ccode_type_name (ObjectTypeSymbol sym) {
                return get_ccode_attribute (sym).type_name;
        }
index 12bd99db24cf09edafb8636281cf57f8c5ba046d..814c14c8ef434219d66b5697124e5fb3c2867aad 100644 (file)
@@ -5404,8 +5404,23 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        public override void visit_sizeof_expression (SizeofExpression expr) {
                generate_type_declaration (expr.type_reference, cfile);
 
+               string struct_name;
+               unowned DataType data_type = expr.type_reference;
+               if (data_type is PointerType) {
+                       if (!(((PointerType) data_type).base_type is VoidType)) {
+                               Report.warning (expr.source_reference, "Passing a pointer-type to `sizeof()' defaults to `sizeof(void*)'");
+                       }
+                       struct_name = "void*";
+               } else if (data_type is ValueType && data_type.nullable) {
+                       // boxed-types are pointers too
+                       Report.warning (expr.source_reference, "Passing a boxed-type to `sizeof()' defaults to `sizeof(void*)'");
+                       struct_name = "void*";
+               } else {
+                       struct_name = get_ccode_struct_name (data_type);
+               }
+
                var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
-               csizeof.add_argument (new CCodeIdentifier (get_ccode_name (expr.type_reference)));
+               csizeof.add_argument (new CCodeIdentifier (struct_name));
                set_cvalue (expr, csizeof);
        }
 
index 329fb8795e2b9c1ec2811c2fae971ca3d8598932..e4567227a3a7f413b5c79499883168f467d9716c 100644 (file)
@@ -615,6 +615,7 @@ TESTS = \
        objects/bug695671.vala \
        objects/bug702736.vala \
        objects/bug702846.vala \
+       objects/bug728274.vala \
        objects/bug731547.vala \
        objects/bug741465.vala \
        objects/bug751338.vala \
diff --git a/tests/objects/bug728274.vala b/tests/objects/bug728274.vala
new file mode 100644 (file)
index 0000000..9b081dc
--- /dev/null
@@ -0,0 +1,36 @@
+class Foo {
+}
+
+[Compact]
+class FooCompact {
+       public int i;
+}
+
+class FooObject : Object {
+}
+
+struct Bar {
+       public int i;
+}
+
+enum Manam {
+       NONE;
+}
+
+errordomain FooError {
+       FAIL;
+}
+
+void main () {
+       assert (sizeof (Foo) >= sizeof (GLib.TypeInstance) + sizeof (int) + sizeof (void*));
+       assert (sizeof (FooCompact) == sizeof (int));
+       assert (sizeof (FooObject) == sizeof (GLib.Object) + sizeof (void*));
+
+       assert (sizeof (Bar) == sizeof (int));
+       assert (sizeof (Manam) == sizeof (uint));
+
+       assert (sizeof (FooError) == sizeof (GLib.Quark) + sizeof (int) + sizeof (void*));
+
+       assert (sizeof (Foo*) == sizeof (void*));
+       assert (sizeof (int?) == sizeof (void*));
+}