p4lang / p4c

P4_16 reference compiler
https://p4.org/
Apache License 2.0
679 stars 444 forks source link

Type is not convertible to string #3509

Open VolodymyrPeschanenkoIntel opened 2 years ago

VolodymyrPeschanenkoIntel commented 2 years ago

The attached small example finished with the message: terminate called after throwing an instance of 'std::runtime_error' what(): Type is not convertible to string I think that the problem is on non-concrete indexes represented by local variables. parser-unroll-test1-bmv2.p4.txt parser-unroll-test1-bmv2.stf.txt

VolodymyrPeschanenkoIntel commented 2 years ago

parser-unroll-test1-bmv2.json.txt

antoninbas commented 2 years ago

This is the stack trace:

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
p4lang/behavioral-model#1  0x00007ffff53ff7f1 in __GI_abort () at abort.c:79
p4lang/behavioral-model#2  0x00007ffff6011957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
p4lang/behavioral-model#3  0x00007ffff6017ae6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
p4lang/behavioral-model#4  0x00007ffff6017b21 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
p4lang/behavioral-model#5  0x00007ffff6017d54 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
p4lang/behavioral-model#6  0x0000555555762704 in Json::Value::asString[abi:cxx11]() const (this=<optimized out>) at src/jsoncpp.cpp:3111
p4lang/behavioral-model#7  0x000055555568ba7b in bm::P4Objects::init_parsers (this=this@entry=0x555555a38650, cfg_root=..., init_state=init_state@entry=0x7fffffffd230) at P4Objects.cpp:973
p4lang/behavioral-model#8  0x000055555569c444 in bm::P4Objects::init_objects (this=0x555555a38650, is=<optimized out>, lookup_factory=0x555555a16680 <bm::SwitchWContexts::default_lookup_factory>, device_id=0, cxt_id=0, 
    notifications_transport=std::shared_ptr<bm::TransportIface> (use count 6, weak count 0) = {...}, required_fields=std::set with 5 elements = {...}, arith_objects=...) at P4Objects.cpp:2183
p4lang/behavioral-model#9  0x00005555556c31a9 in bm::Context::init_objects (this=this@entry=0x555555a35c00, is=is@entry=0x7fffffffd7d0, lookup_factory=<optimized out>, required_fields=..., arith_objects=...)
    at context.cpp:805
p4lang/behavioral-model#10 0x0000555555756642 in bm::SwitchWContexts::init_objects (this=this@entry=0x555555a362c0, is=is@entry=0x7fffffffd7d0, dev_id=dev_id@entry=0, 
    transport=std::shared_ptr<bm::TransportIface> (empty) = {...}) at switch.cpp:170
p4lang/behavioral-model#11 0x0000555555756b8b in bm::SwitchWContexts::init_objects (this=this@entry=0x555555a362c0, json_path="/tmp/parser-unroll-test1-bmv2.json", dev_id=0, 
    transport=std::shared_ptr<bm::TransportIface> (use count 6, weak count 0) = {...}) at switch.cpp:191
p4lang/behavioral-model#12 0x0000555555757164 in bm::SwitchWContexts::init_from_options_parser (this=0x555555a362c0, parser=..., my_transport=..., my_dev_mgr=std::unique_ptr<bm::DevMgrIface> = {...}) at switch.cpp:263
p4lang/behavioral-model#13 0x000055555562983c in main (argc=<optimized out>, argv=<optimized out>) at main.cpp:84

There is the following parser state in the JSON:

        {
          "name" : "parse_srcRouting",
          "id" : 1,
          "parser_ops" : [
            {
              "parameters" : [
                {
                  "type" : "regular",
                  "value" : {
                    "type" : "expression",
                    "value" : {
                      "op" : "dereference_header_stack",
                      "left" : {
                        "type" : "header_stack",
                        "value" : "srcRoutes"
                      },
                      "right" : {
                        "type" : "field",
                        "value" : ["scalars", "index_0"]
                      }
                    }
                  }
                }
              ],
              "op" : "extract"
            },
...

As per the spec, this extract operation is not valid. You can only do a regular extract to a header reference, which is why bmv2 is expecting a string there. More generally, the bmv2 parser implementation cannot do an extract with an expression as the operand. It must be a string reference to a header, a stack, etc.

A correct JSON would first extract to a temporary header, then do the appropriate copy with an assign_header operation.