From aa41b1bc7520da91c2483e6237fd4658c69daf25 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 8 Sep 2026 11:15:36 -0400 Subject: [PATCH] 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 --- tools/net/sunrpc/xdrgen/xdr_ast.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 2d51add317f7..49766a10717e 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -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