[vala/staging] codegen: Avoid passing a pointer to sizeof() if is not intended



commit e0b8125810c8a4ffd38954b512e019a3eec32c21
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu Mar 8 13:57:29 2018 +0100

    codegen: Avoid passing a pointer to sizeof() if is not intended
    
    Additionally adds "struct_cname" CCode attribute.
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/442

 codegen/valaccode.vala           |  4 ++++
 codegen/valaccodeattribute.vala  | 36 +++++++++++++++++++++++++++++++
 codegen/valaccodebasemodule.vala | 20 ++++++++++++++++-
 tests/Makefile.am                |  1 +
 tests/objects/bug728274.vala     | 46 ++++++++++++++++++++++++++++++++++++++++
 vala/valausedattr.vala           |  2 +-
 6 files changed, 107 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valaccode.vala b/codegen/valaccode.vala
index 1bb92171e..e8e1cf651 100644
--- a/codegen/valaccode.vala
+++ b/codegen/valaccode.vala
@@ -45,6 +45,10 @@ namespace Vala {
                return get_ccode_attribute(node).const_name;
        }
 
+       public static string get_ccode_struct_name (CodeNode node) {
+               return get_ccode_attribute(node).struct_name;
+       }
+
        public static string get_ccode_type_name (Interface iface) {
                return get_ccode_attribute(iface).type_name;
        }
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index b6f60498c..138935eda 100644
--- a/codegen/valaccodeattribute.vala
+++ b/codegen/valaccodeattribute.vala
@@ -57,6 +57,20 @@ public class Vala.CCodeAttribute : AttributeCache {
                }
        }
 
+       public string struct_name {
+               get {
+                       if (_struct_name == null) {
+                               if (ccode != null) {
+                                       _struct_name = ccode.get_string ("struct_cname");
+                               }
+                               if (_struct_name == null) {
+                                       _struct_name = get_default_struct_name ();
+                               }
+                       }
+                       return _struct_name;
+               }
+       }
+
        public string type_name {
                get {
                        if (_type_name == null) {
@@ -572,6 +586,7 @@ public class Vala.CCodeAttribute : AttributeCache {
 
        private string _name;
        private string _const_name;
+       private string _struct_name;
        private string _type_name;
        private string _feature_test_macros;
        private string _header_filenames;
@@ -783,6 +798,27 @@ public class Vala.CCodeAttribute : AttributeCache {
                }
        }
 
+       private string get_default_struct_name () {
+               unowned DataType? data_type = node as DataType;
+
+               if (data_type is ObjectType) {
+                       return get_ccode_name (((ObjectType) data_type).type_symbol);
+               } else if (data_type is ErrorType) {
+                       return "GError";
+               } else if (data_type is ClassType) {
+                       return "%sClass".printf (get_ccode_name (((ClassType) data_type).class_symbol));
+               } else if (data_type is InterfaceType) {
+                       return get_ccode_type_name (((InterfaceType) data_type).interface_symbol);
+               } else if (data_type is ValueType && !data_type.nullable) {
+                       return get_ccode_name (((ValueType) data_type).type_symbol);
+               } else if (node is CType) {
+                       return ((CType) node).ctype_name;
+               }
+
+               Report.error (node.source_reference, "internal error: `%s' doesn't have a struct name".printf 
(node.type_name));
+               return "";
+       }
+
        private string get_default_header_filenames () {
                if (sym is DynamicProperty || sym is DynamicMethod) {
                        return "";
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 2da65098a..91fda5a91 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -5067,8 +5067,26 @@ 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 if (data_type is GenericType) {
+                       // generic-types are represented by gpointer
+                       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);
        }
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d03e394c1..9dbd86508 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -299,6 +299,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
index 000000000..570c5678d
--- /dev/null
+++ b/tests/objects/bug728274.vala
@@ -0,0 +1,46 @@
+class Foo {
+}
+
+[Compact]
+class FooCompact {
+       public int i;
+}
+
+class FooObject : Object {
+}
+
+struct Bar {
+       public int i;
+}
+
+enum Manam {
+       NONE;
+}
+
+errordomain FooError {
+       FAIL;
+}
+
+void generic<G> (G bar) {
+       assert (sizeof (G) == sizeof (void*));
+}
+
+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*));
+
+       assert (sizeof (int8) == 1);
+       assert (sizeof (int16) == 2);
+       assert (sizeof (int32) == 4);
+
+       generic<Foo> (new Foo ());
+}
diff --git a/vala/valausedattr.vala b/vala/valausedattr.vala
index dab15a864..69a542362 100644
--- a/vala/valausedattr.vala
+++ b/vala/valausedattr.vala
@@ -31,7 +31,7 @@ public class Vala.UsedAttr : CodeVisitor {
 
        const string[] valac_default_attrs = {
                "CCode", "type_signature", "default_value", "set_value_function", "type_id", "cprefix", 
"cheader_filename",
-               "marshaller_type_name", "get_value_function", "cname", "destroy_function", "lvalue_access",
+               "marshaller_type_name", "get_value_function", "cname", "struct_cname", "destroy_function", 
"lvalue_access",
                "has_type_id", "instance_pos", "const_cname", "take_value_function", "copy_function", 
"free_function",
                "param_spec_function", "has_target", "has_typedef", "type_cname", "ref_function", 
"ref_function_void", "unref_function", "type",
                "has_construct_function", "returns_floating_reference", "gir_namespace", "gir_version", 
"construct_function",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]