xdrgen: Generate "if" instead of "switch" for boolean union enumerators

Eliminate this warning in code generated by xdrgen:

fs/nfsd/nfs3xdr_gen.c:220:2: warning: switch condition has boolean value [-Wswitch-bool]
  220 |         switch (ptr->attributes_follow) {
      |         ^       ~~~~~~~~~~~~~~~~~~~~~~

No more -Wswitch-bool warnings when compiling with W=1.

The generated code is functionally equivalent but somewhat more
idiomatic.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202511172336.Y75zj4v6-lkp@intel.com/
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Chuck Lever
2025-11-20 15:15:52 -05:00
parent e344a031a4
commit 9654a0388a
3 changed files with 109 additions and 20 deletions

View File

@@ -84,6 +84,31 @@ def emit_union_switch_spec_decoder(
print(template.render(name=node.name, type=node.spec.type_name))
def emit_union_arm_decoder(
environment: Environment, node: _XdrCaseSpec
) -> None:
"""Emit decoder for an XDR union's arm (data only, no case/break)"""
if isinstance(node.arm, _XdrVoid):
return
if isinstance(node.arm, _XdrString):
type_name = "char *"
classifier = ""
else:
type_name = node.arm.spec.type_name
classifier = node.arm.spec.c_classifier
assert isinstance(node.arm, (_XdrBasic, _XdrString))
template = get_jinja2_template(environment, "decoder", node.arm.template)
print(
template.render(
name=node.arm.name,
type=type_name,
classifier=classifier,
)
)
def emit_union_case_spec_decoder(
environment: Environment, node: _XdrCaseSpec, big_endian_discriminant: bool
) -> None:
@@ -151,19 +176,33 @@ def emit_union_decoder(environment: Environment, node: _XdrUnion) -> None:
template = get_jinja2_template(environment, "decoder", "open")
print(template.render(name=node.name))
emit_union_switch_spec_decoder(environment, node.discriminant)
# For boolean discriminants, use if statement instead of switch
if node.discriminant.spec.type_name == "bool":
template = get_jinja2_template(environment, "decoder", "bool_spec")
print(template.render(name=node.discriminant.name, type=node.discriminant.spec.type_name))
for case in node.cases:
emit_union_case_spec_decoder(
environment,
case,
node.discriminant.spec.type_name in big_endian,
)
# Find and emit the TRUE case
for case in node.cases:
if case.values and case.values[0] == "TRUE":
emit_union_arm_decoder(environment, case)
break
emit_union_default_spec_decoder(environment, node)
template = get_jinja2_template(environment, "decoder", "close")
print(template.render())
else:
emit_union_switch_spec_decoder(environment, node.discriminant)
template = get_jinja2_template(environment, "decoder", "close")
print(template.render())
for case in node.cases:
emit_union_case_spec_decoder(
environment,
case,
node.discriminant.spec.type_name in big_endian,
)
emit_union_default_spec_decoder(environment, node)
template = get_jinja2_template(environment, "decoder", "close")
print(template.render())
def emit_union_switch_spec_encoder(
@@ -175,6 +214,28 @@ def emit_union_switch_spec_encoder(
print(template.render(name=node.name, type=node.spec.type_name))
def emit_union_arm_encoder(
environment: Environment, node: _XdrCaseSpec
) -> None:
"""Emit encoder for an XDR union's arm (data only, no case/break)"""
if isinstance(node.arm, _XdrVoid):
return
if isinstance(node.arm, _XdrString):
type_name = "char *"
else:
type_name = node.arm.spec.type_name
assert isinstance(node.arm, (_XdrBasic, _XdrString))
template = get_jinja2_template(environment, "encoder", node.arm.template)
print(
template.render(
name=node.arm.name,
type=type_name,
)
)
def emit_union_case_spec_encoder(
environment: Environment, node: _XdrCaseSpec, big_endian_discriminant: bool
) -> None:
@@ -235,19 +296,33 @@ def emit_union_encoder(environment, node: _XdrUnion) -> None:
template = get_jinja2_template(environment, "encoder", "open")
print(template.render(name=node.name))
emit_union_switch_spec_encoder(environment, node.discriminant)
# For boolean discriminants, use if statement instead of switch
if node.discriminant.spec.type_name == "bool":
template = get_jinja2_template(environment, "encoder", "bool_spec")
print(template.render(name=node.discriminant.name, type=node.discriminant.spec.type_name))
for case in node.cases:
emit_union_case_spec_encoder(
environment,
case,
node.discriminant.spec.type_name in big_endian,
)
# Find and emit the TRUE case
for case in node.cases:
if case.values and case.values[0] == "TRUE":
emit_union_arm_encoder(environment, case)
break
emit_union_default_spec_encoder(environment, node)
template = get_jinja2_template(environment, "encoder", "close")
print(template.render())
else:
emit_union_switch_spec_encoder(environment, node.discriminant)
template = get_jinja2_template(environment, "encoder", "close")
print(template.render())
for case in node.cases:
emit_union_case_spec_encoder(
environment,
case,
node.discriminant.spec.type_name in big_endian,
)
emit_union_default_spec_encoder(environment, node)
template = get_jinja2_template(environment, "encoder", "close")
print(template.render())
def emit_union_maxsize(environment: Environment, node: _XdrUnion) -> None:

View File

@@ -0,0 +1,7 @@
{# SPDX-License-Identifier: GPL-2.0 #}
{% if annotate %}
/* discriminant {{ name }} */
{% endif %}
if (!xdrgen_decode_{{ type }}(xdr, &ptr->{{ name }}))
return false;
if (ptr->{{ name }}) {

View File

@@ -0,0 +1,7 @@
{# SPDX-License-Identifier: GPL-2.0 #}
{% if annotate %}
/* discriminant {{ name }} */
{% endif %}
if (!xdrgen_encode_{{ type }}(xdr, ptr->{{ name }}))
return false;
if (ptr->{{ name }}) {