Skip to content

Reject duplicate match_kind declarations#5656

Open
aeron-gh wants to merge 1 commit into
p4lang:mainfrom
aeron-gh:reject-duplicate-match-kind
Open

Reject duplicate match_kind declarations#5656
aeron-gh wants to merge 1 commit into
p4lang:mainfrom
aeron-gh:reject-duplicate-match-kind

Conversation

@aeron-gh

Copy link
Copy Markdown

Fixes #5085.

The P4-16 spec (section 7.1.3) says all match_kind identifiers are inserted into the top-level namespace and that it is an error to declare the same one more than once. The frontend already enforced this within a single match_kind block, but duplicates spread across separate blocks were silently accepted, e.g.:

match_kind { foo, bar }
match_kind { foo }       // not rejected

This also let programs redeclare a match_kind already defined by core.p4 (the existing pipe.p4 sample did exactly this).

Approach

error declarations already have this exact behavior, so I followed the same pattern:

  • P4ParserDriver now merges every match_kind declaration into a single node (onReadMatchKindDeclaration), the same way onReadErrorDeclaration works. Appending the members into the shared IndexedVector is what makes the existing duplicate-declaration check fire across blocks.
  • Because the merged node inherits the source location of the first declaration (usually core.p4), ToP4 is taught to always visit Declaration_MatchKind and print only the user-defined members, mirroring how Type_Error is handled. Otherwise user-added match_kinds would be hidden behind the #include.

Test / sample updates

  • New error test decl-matchkind-with-duplicate-fields-in-separate-declarations covers duplicates across separate blocks.
  • pipe.p4 redeclared ternary and exact from core.p4; that redundant block is removed.
  • Samples that add genuinely new match_kinds (issue982, the two dash pipelines) now print that block right after the include, the same way merged error blocks are emitted. Reference outputs are regenerated accordingly.

Per P4-16 spec section 7.1.3, all match_kind identifiers are inserted into
the top-level namespace and it is an error to declare the same one more
than once. p4c already enforced this within a single match_kind block but
silently accepted duplicates spread across separate blocks, including the
common case of a program redeclaring a match_kind that core.p4 already
defines.

Handle match_kind the same way the frontend already handles error: the
parser driver merges every match_kind declaration into a single node, so
IndexedVector emits the duplicate-declaration error, and ToP4 prints only
the user-defined members so the merged node is not hidden behind the
system include.

pipe.p4 redeclared ternary and exact from core.p4, so its redundant block
is removed. Other samples that add genuinely new match_kinds now print
that block next to the include, mirroring how error blocks are emitted.

Fixes p4lang#5085

Signed-off-by: aeron-gh <agab0323@gmail.com>
@aeron-gh aeron-gh force-pushed the reject-duplicate-match-kind branch from 0329297 to 14b30a0 Compare June 16, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate match_kind declarations are allowed when they shoudn't

1 participant