Skip to content

Ivy generates incorrect C++ code when using a range type (iterable) #84

Description

@nano-o

Ivy generates incorrect C++ code (does not compile) in this example, where I was trying to implement vector clocks in the most straightforward way possible. In the C++, the max of the pid_t range type is a member of the main class but the C++ code sometimes tries to access it as it if were a global static variable. Moreover there is a constness issue caused by the memo table in hash_thunk.

#lang ivy1.8

include order

instance pid_t : iterable
instance clock_t : unbounded_sequence

object vector_clock_t = {
    type this = struct {
        component(P:pid_t): clock_t
    }

    action empty returns (vc:this)
    action merge(vc1:this, vc2:this) returns (vc:this)
    action incr(vc:this, p:pid_t) returns (vc:this)

    implementation {
        implement empty {
            component(vc, P) := 0
        }
        implement merge {
            component(vc, P) := component(vc2, P) if component(vc2,P) > component(vc1,P) else component(vc1, P)
        }
        implement incr {
            var s := component(vc, p).next;
            component(vc, P) := s if P = p else component(vc, P)
        }
    }
}

export vector_clock_t.empty
export vector_clock_t.merge
export vector_clock_t.incr

extract impl = this, vector_clock_t, pid_t, clock_t
$ ivyc isolate=impl struct_clock.ivy
g++ -Wno-parentheses-equality  -std=c++11   -g -o struct_clock struct_clock.cpp -pthread
In file included from struct_clock.cpp:1:
struct_clock.h: In function ‘bool operator==(const struct_clock::vector_clock_t&, const struct_clock::vector_clock_t&)’:
struct_clock.h:656:27: error: ‘pid_t__max’ was not declared in this scope
  656 |     for (int X0 = 0; X0 < pid_t__max+1; X0++) {
      |                           ^~~~~~~~~~
struct_clock.h:657:29: error: passing ‘const hash_thunk<int, long long unsigned int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  657 |         if (!(s.component[X0] == t.component[X0])) __tmp3 = 0;
      |                             ^
struct_clock.h:592:8: note:   in call to ‘R& hash_thunk<D, R, HashFun>::operator[](const D&) [with D = int; R = long long unsigned int; HashFun = hash_space::hash<int>]’
  592 |     R &operator[](const D& arg){
      |        ^~~~~~~~
struct_clock.h:657:48: error: passing ‘const hash_thunk<int, long long unsigned int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  657 |         if (!(s.component[X0] == t.component[X0])) __tmp3 = 0;
      |                                                ^
struct_clock.h:592:8: note:   in call to ‘R& hash_thunk<D, R, HashFun>::operator[](const D&) [with D = int; R = long long unsigned int; HashFun = hash_space::hash<int>]’
  592 |     R &operator[](const D& arg){
      |        ^~~~~~~~
struct_clock.cpp: In function ‘std::ostream& operator<<(std::ostream&, const struct_clock::vector_clock_t&)’:
struct_clock.cpp:703:32: error: ‘pid_t__max’ was not declared in this scope
  703 |     for (int X__0 = 0; X__0 < (pid_t__max+1); X__0++) {
      |                                ^~~~~~~~~~
struct_clock.cpp:705:30: error: passing ‘const hash_thunk<int, long long unsigned int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  705 |         s << t.component[X__0];
      |                              ^
In file included from struct_clock.cpp:1:
struct_clock.h:592:8: note:   in call to ‘R& hash_thunk<D, R, HashFun>::operator[](const D&) [with D = int; R = long long unsigned int; HashFun = hash_space::hash<int>]’
  592 |     R &operator[](const D& arg){
      |        ^~~~~~~~
struct_clock.cpp: In function ‘void __ser(ivy_ser&, const T&) [with T = struct_clock::vector_clock_t]’:
struct_clock.cpp:714:32: error: ‘pid_t__max’ was not declared in this scope
  714 |     for (int X__0 = 0; X__0 < (pid_t__max+1); X__0++) {
      |                                ^~~~~~~~~~
struct_clock.cpp:716:55: error: passing ‘const hash_thunk<int, long long unsigned int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  716 |         __ser<unsigned long long>(res,t.component[X__0]);
      |                                                       ^
In file included from struct_clock.cpp:1:
struct_clock.h:592:8: note:   in call to ‘R& hash_thunk<D, R, HashFun>::operator[](const D&) [with D = int; R = long long unsigned int; HashFun = hash_space::hash<int>]’
  592 |     R &operator[](const D& arg){
      |        ^~~~~~~~
struct_clock.cpp: In function ‘T _arg(std::vector<ivy_value>&, unsigned int, long long int) [with T = struct_clock::vector_clock_t]’:
struct_clock.cpp:898:32: error: ‘pid_t__max’ was not declared in this scope
  898 |     for (int X__0 = 0; X__0 < (pid_t__max+1); X__0++) {
      |                                ^~~~~~~~~~
struct_clock.cpp:910:48: error: ‘pid_t__max’ was not declared in this scope
  910 |                     for (int X__0 = 0; X__0 < (pid_t__max+1); X__0++) {
      |                                                ^~~~~~~~~~
struct_clock.cpp: In function ‘void __deser(ivy_deser&, T&) [with T = struct_clock::vector_clock_t]’:
struct_clock.cpp:933:32: error: ‘pid_t__max’ was not declared in this scope
  933 |     for (int X__0 = 0; X__0 < (pid_t__max+1); X__0++) {
      |                                ^~~~~~~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions