Skip to content

Comparisons of list expressions, structure-valued expressions, tuples and structs #3057

Closed
@MollyDream

Description

In testing all the comparisons between list expressions, structure-valued expressions, tuples, and structs in the p4c compiler, we found some examples rejected by the compiler (relates to p4lang/p4-spec#960). Some are likely compiler bugs, while some may not be.

Note: the tests are reordered and renumbered for a cleaner view, so it looks different from p4lang/p4-spec#960.

struct S {
    bit<32> a;
    bit<32> b;
}

control compute(inout hdr h) {
    apply {
        bool b1 = { 1, 2 } == { 1, 2 };

        bool b2 = { a = 8w1, b = 8w2 } == { a = 8w1, b = 8w2 };
         // bool b2_ = { a = 1, b = 2 } == { a = 1, b = 2 }; // p4c: Compiler Bug: Could not find type for <Constant>(11032) 1

         // bool b3 = { a = 1, b = 2 } == {1, 2};  // p4c: error: ==: Cannot unify type Tuple(2) with unknown struct
        bool b4 = (S) { a = 1, b = 2 } == {1, 2};

        bool b5 = (S) { a = 1, b = 2 } == { a = 1, b = 2 };
        // bool b5_ = { a = 1, b = 2 } == (S) { a = 1, b = 2 }; // p4c: error: ==: Cannot unify struct S to unknown struct
       
        bool b6 = (S) { a = 1, b = 2 } == (S) { a = 1, b = 2 };

        S s1 = { a = 1, b = 2 };
        S s2 = { a = 1, b = 2 };
        bool b7 = s1 == { a = 1, b = 2 };
        bool b8 = s1 == (S) { a = 1, b = 2 };
        bool b9 = s1 == s2;

        tuple<bit<8>, bit<8>> t1 = {1, 2};
        tuple<bit<8>, bit<8>> t2 = {1, 2};
        bool b10 = t1 == { 1, 2 };
        bool b11 = t1 == t2;
    }
}

The tests b2_ and b5_ are likely bugs.

  • For b2_, it seems to be some other issue with the compiler since b2 works well.
  • For b5_, it seems weird that the compiler cannot infer the type of the LHS. Given that b5 works well, and there is no rule in the spec enforcing the direction of type inference, I think it is more likely a problem with the compiler.

With the test b3 aside, it seems tempting to summarize the allowed comparisons as:

  • A list expression can be compared with a list expression, a structure-valued expression, a tuple, a struct, or a header for
    equality (==) or inequality (!=)
  • A structure-valued expression can be compared with a list expression, a structure-valued expression, a struct, or a header for
    equality (==) or inequality (!=)
  • Two tuples, two structs, and two headers can be compared for equality (==) or inequality (!=)

But the test b3 is indeed the corner case. Comparing b3 and b4, a list expression can be compared with a structure-valued expression only when typRef is explicit. We are still unsure whether b3 should be allowed or not: if yes, then the compiler needs to be fixed; otherwise, we need a more careful specification in the spec to explain this well.

Metadata

Assignees

Labels

bugThis behavior is unintended and should be fixed.coreTopics concerning the core segments of the compiler (frontend, midend, parser)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions