xdrgen: Reject a "pragma pages" union arm declared as an opaque

check_pages_directives() rejects a union arm declared directly as
a string, with a diagnostic pointing at the directive, but accepts
one declared directly as a variable-length opaque. The union
generator has no arm representation for a direct opaque, so
generation fails with an AttributeError from
emit_union_case_spec_definition() instead. A direct opaque arm was
never generated correctly, marked or not, but the pages validation
exists to report such a directive at its source position.

Extend the union-arm check to a direct variable-length opaque, so
both forms draw the same diagnostic.

Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
Chuck Lever 2026-09-08 11:15:36 -04:00
parent 1e7f9d30d5
commit aa41b1bc75

View File

@ -1131,12 +1131,16 @@ def check_pages_directives(root: "Specification") -> None:
field, container = members[marked[1]]
# A union arm declared directly as a string is generated as
# a char *, with no length field for the page encoder to
# read; inside a struct it becomes a { len, data } object.
if isinstance(container, _XdrUnion) and isinstance(field, _XdrString):
# read, and the union generator has no arm representation
# for a direct opaque at all; inside a struct either
# becomes a { len, data } object.
if isinstance(container, _XdrUnion) and isinstance(
field, (_XdrString, _XdrVariableLengthOpaque)
):
raise XdrSemanticError(
f"union arm '{type_name}.{marked[1]}' is declared"
" directly as a string and carries no length field;"
" declare it through a typedef instead",
" directly as a string or opaque; declare it through"
" a typedef instead",
meta,
)
# A decoded member and an encoded one take different C