After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 588280 - memset code generation is incorrect
memset code generation is incorrect
Status: RESOLVED INVALID
Product: vala
Classification: Core
Component: Code Generator
0.7.x
Other All
: Normal critical
: ---
Assigned To: Jürg Billeter
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2009-07-10 21:26 UTC by Michael Trausch
Modified: 2009-07-21 20:51 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Michael Trausch 2009-07-10 21:26:00 UTC
Please describe the problem:
When using a simple C struct defined in a binding, Vala fails to compile the code correctly.  It does this:

 f = memset(0, sizeof(thing))

When it should be doing this:

 memset(&f, 0, sizeof(thing))

In a run (with the sample code below) the following output is had when compiling to a C file:

** (valac:8573): CRITICAL **: vala_ccode_unary_expression_construct: assertion `expr != NULL' failed

** (valac:8573): CRITICAL **: vala_ccode_function_call_add_argument: assertion `expr != NULL' failed

Of course, when attempting to build the executable, GCC refuses to build the generated code.

Steps to reproduce:
1. Use the VAPI and Vala source files shown below.
2. Attempt to build them.
3. Boom.

Actual results:
Boom.

Expected results:
Correct generation of the C code. (Oh, bugzilla, why do you ask this... what _else_ would I expect to happen...?)

Does this happen every time?
Yes.

Other information:
The VAPI:
/*
 * mbt0_test.vapi - Cause Vala to not init memory correctly.
 */

[CCode(cprefix = "", lower_case_cprefix = "")]
namespace mbt0Test {
  [SimpleType]
  [IntegerType]
  [CCode(cheader_filename = "sys/socket.h")]
  public struct in_addr_t {
  }

  [SimpleType]
  [CCode(cname = "struct in_addr",
	 cheader_filename = "arpa/inet.h,sys/socket.h")]
  public struct in_addr {
    public in_addr_t s_addr;
  }
}

The Vala source file:
/*
 * mbt0_test.vala - Cause Vala to not init memory correctly.
 */

public class TestProgram {
  public static int main(string[] args) {
    mbt0Test.in_addr addr = mbt0Test.in_addr();
    addr.s_addr = 0;

    return(0);
  }
}
Comment 1 Michael Trausch 2009-07-10 21:33:21 UTC
Here is the output of a gdb session on my copy of Vala when I hit this bug compiling the test code shown in the main description:

Friday, 2009-Jul-10 at 17:31:39 - mbt@zest - Linux v2.6.30.1
Ubuntu Jaunty:[5-135/10154-0]:bugs> gdb valac                                       
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu"...
(gdb) start --vapidir . --pkg mbt0_test mbt0_test.vala -C
Breakpoint 1 at 0x406a14: file valacompiler.c, line 1108.
Starting program: /usr/local/bin/valac --vapidir . --pkg mbt0_test mbt0_test.vala -C
main (argc=7, argv=0x7fff1f9f7b28) at valacompiler.c:1108
1108		g_type_init ();
(gdb) break vala_ccode_unary_expression_construct
Breakpoint 2 at 0x7f065c108af7: file valaccodeunaryexpression.c, line 174.
(gdb) xont
Undefined command: "xont".  Try "help".
(gdb) cont
Continuing.

Breakpoint 2, vala_ccode_unary_expression_construct (object_type=33716336, op=VALA_CCODE_UNARY_OPERATOR_ADDRESS_OF, expr=0x0) at valaccodeunaryexpression.c:174
174		g_return_val_if_fail (expr != NULL, NULL);
(gdb) bt full
  • #0 vala_ccode_unary_expression_construct
    at valaccodeunaryexpression.c line 174
  • #1 vala_ccode_unary_expression_new
    at valaccodeunaryexpression.c line 183
  • #2 vala_ccode_base_module_real_visit_object_creation_expression
    at valaccodebasemodule.c line 8202
  • #3 vala_ccode_module_visit_object_creation_expression
    at valaccodemodule.c line 1038
  • #4 vala_ccode_generator_real_visit_object_creation_expression
    at valaccodegenerator.c line 894
  • #5 vala_code_visitor_visit_object_creation_expression
    at valacodevisitor.c line 2168
  • #6 vala_object_creation_expression_real_accept
    at valaobjectcreationexpression.c line 1457
  • #7 vala_code_node_accept
    at valacodenode.c line 344
  • #8 vala_local_variable_real_accept_children
    at valalocalvariable.c line 419
  • #9 vala_code_node_accept_children
    at valacodenode.c line 360
  • #10 vala_ccode_base_module_real_visit_local_variable
    at valaccodebasemodule.c line 4236
  • #11 vala_ccode_module_visit_local_variable
    at valaccodemodule.c line 654
  • #12 vala_ccode_generator_real_visit_local_variable
    at valaccodegenerator.c line 638
  • #13 vala_code_visitor_visit_local_variable
    at valacodevisitor.c line 1624
  • #14 vala_local_variable_real_accept
    at valalocalvariable.c line 410
  • #15 vala_code_node_accept
    at valacodenode.c line 344
  • #16 vala_ccode_base_module_real_visit_declaration_statement
    at valaccodebasemodule.c line 4145
  • #17 vala_ccode_module_visit_declaration_statement
    at valaccodemodule.c line 642
  • #18 vala_ccode_generator_real_visit_declaration_statement
    at valaccodegenerator.c line 630
  • #19 vala_code_visitor_visit_declaration_statement
    at valacodevisitor.c line 1608
  • #20 vala_declaration_statement_real_accept
    at valadeclarationstatement.c line 278
  • #21 vala_code_node_accept
    at valacodenode.c line 344
  • #22 vala_block_real_accept_children
    at valablock.c line 1439
  • #23 vala_code_node_accept_children
    at valacodenode.c line 360
  • #24 vala_ccode_base_module_real_visit_block
    at valaccodebasemodule.c line 3955
  • #25 vala_ccode_module_visit_block
    at valaccodemodule.c line 618
  • #26 vala_ccode_generator_real_visit_block
    at valaccodegenerator.c line 614
  • #27 vala_code_visitor_visit_block
    at valacodevisitor.c line 1576
  • #28 vala_block_real_accept
    at valablock.c line 1422
  • #29 vala_code_node_accept
    at valacodenode.c line 344
  • #30 vala_method_real_accept_children
    at valamethod.c line 1648
  • #31 vala_code_node_accept_children
    at valacodenode.c line 360
  • #32 vala_ccode_method_module_real_visit_method
    at valaccodemethodmodule.c line 957
  • #33 vala_gasync_module_real_visit_method
    at valagasyncmodule.c line 1284
  • #34 vala_ccode_module_visit_method
    at valaccodemodule.c line 522
  • #35 vala_ccode_generator_real_visit_method
    at valaccodegenerator.c line 550
  • #36 vala_code_visitor_visit_method
    at valacodevisitor.c line 1400
  • #37 vala_method_real_accept
    at valamethod.c line 1573
  • #38 vala_code_node_accept
    at valacodenode.c line 344
  • #39 vala_class_real_accept_children
    at valaclass.c line 2042
  • #40 vala_code_node_accept_children
    at valacodenode.c line 360
  • #41 vala_gtype_module_real_visit_class
    at valagtypemodule.c line 2024
  • #42 vala_gobject_module_real_visit_class
    at valagobjectmodule.c line 619
  • #43 vala_ccode_module_visit_class
    at valaccodemodule.c line 414
  • #44 vala_ccode_generator_real_visit_class
    at valaccodegenerator.c line 478
  • #45 vala_code_visitor_visit_class
    at valacodevisitor.c line 1224
  • #46 vala_class_real_accept
    at valaclass.c line 1945
  • #47 vala_code_node_accept
    at valacodenode.c line 344
  • #48 vala_source_file_accept_children
    at valasourcefile.c line 432
  • #49 vala_ccode_base_module_real_visit_source_file
    at valaccodebasemodule.c line 1200
  • #50 vala_ccode_module_visit_source_file
    at valaccodemodule.c line 402
  • #51 vala_ccode_generator_real_visit_source_file
    at valaccodegenerator.c line 470
  • #52 vala_code_visitor_visit_source_file
    at valacodevisitor.c line 1192
  • #53 vala_source_file_accept
    at valasourcefile.c line 402
  • #54 vala_ccode_base_module_real_emit
    at valaccodebasemodule.c line 822
  • #55 vala_ccode_module_emit
    at valaccodemodule.c line 390
  • #56 vala_ccode_generator_real_emit
    at valaccodegenerator.c line 460
  • #57 vala_code_generator_emit
    at valacodegenerator.c line 1079
  • #58 vala_compiler_run
    at valacompiler.c line 676
  • #59 vala_compiler_main
    at valacompiler.c line 1101
  • #60 main
    at valacompiler.c line 1109

Comment 2 Jürg Billeter 2009-07-13 16:03:11 UTC
The binding appears to be incorrect. in_addr should not be marked as [SimpleType], as far as I can tell. Please reopen the bug if you still have issues with the fixed binding.
Comment 3 Michael Trausch 2009-07-21 20:51:47 UTC
Well, the binding may be incorrect, but that really isn't the issue here.  The issue here is that memset should be zeroing out the memory at the location of the value-type struct.  That is how it would be done in C code.  The problem is that it has shifted the values to the left a spot.  Instead of:

 [nothing] function(p1, p2, p3)

Vala generated:

 p1 = function(p2, p3)

Which is incorrect, this would be the part which is the bug in Vala.  Now, if zeroing out the memory held by the local struct (in this case, just an integer) is bad, why?  Convention seems to be that you declare it in your function, and if you pass it, only then do you take its address (&addr).

All in_addr is:

 struct in_addr {
   uint32_t addr;
 };

It seems that the other BSD sockets related structures all are treated the same way, using a function-local variable instead of a function-local pointer created via malloc.  Makes sense, since it doesn't make much sense to allocate/deallocate memory every time you create one unless you're in a library and passing back a return value, in which case you _should_ return something other than a value from static storage...