Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+109 -20
+95 -20
tools/net/sunrpc/xdrgen/generators/union.py
··· 84 84 print(template.render(name=node.name, type=node.spec.type_name)) 85 85 86 86 87 + def emit_union_arm_decoder( 88 + environment: Environment, node: _XdrCaseSpec 89 + ) -> None: 90 + """Emit decoder for an XDR union's arm (data only, no case/break)""" 91 + 92 + if isinstance(node.arm, _XdrVoid): 93 + return 94 + if isinstance(node.arm, _XdrString): 95 + type_name = "char *" 96 + classifier = "" 97 + else: 98 + type_name = node.arm.spec.type_name 99 + classifier = node.arm.spec.c_classifier 100 + 101 + assert isinstance(node.arm, (_XdrBasic, _XdrString)) 102 + template = get_jinja2_template(environment, "decoder", node.arm.template) 103 + print( 104 + template.render( 105 + name=node.arm.name, 106 + type=type_name, 107 + classifier=classifier, 108 + ) 109 + ) 110 + 111 + 87 112 def emit_union_case_spec_decoder( 88 113 environment: Environment, node: _XdrCaseSpec, big_endian_discriminant: bool 89 114 ) -> None: ··· 176 151 template = get_jinja2_template(environment, "decoder", "open") 177 152 print(template.render(name=node.name)) 178 153 179 - emit_union_switch_spec_decoder(environment, node.discriminant) 154 + # For boolean discriminants, use if statement instead of switch 155 + if node.discriminant.spec.type_name == "bool": 156 + template = get_jinja2_template(environment, "decoder", "bool_spec") 157 + print(template.render(name=node.discriminant.name, type=node.discriminant.spec.type_name)) 180 158 181 - for case in node.cases: 182 - emit_union_case_spec_decoder( 183 - environment, 184 - case, 185 - node.discriminant.spec.type_name in big_endian, 186 - ) 159 + # Find and emit the TRUE case 160 + for case in node.cases: 161 + if case.values and case.values[0] == "TRUE": 162 + emit_union_arm_decoder(environment, case) 163 + break 187 164 188 - emit_union_default_spec_decoder(environment, node) 165 + template = get_jinja2_template(environment, "decoder", "close") 166 + print(template.render()) 167 + else: 168 + emit_union_switch_spec_decoder(environment, node.discriminant) 189 169 190 - template = get_jinja2_template(environment, "decoder", "close") 191 - print(template.render()) 170 + for case in node.cases: 171 + emit_union_case_spec_decoder( 172 + environment, 173 + case, 174 + node.discriminant.spec.type_name in big_endian, 175 + ) 176 + 177 + emit_union_default_spec_decoder(environment, node) 178 + 179 + template = get_jinja2_template(environment, "decoder", "close") 180 + print(template.render()) 192 181 193 182 194 183 def emit_union_switch_spec_encoder( ··· 212 173 assert isinstance(node, _XdrBasic) 213 174 template = get_jinja2_template(environment, "encoder", "switch_spec") 214 175 print(template.render(name=node.name, type=node.spec.type_name)) 176 + 177 + 178 + def emit_union_arm_encoder( 179 + environment: Environment, node: _XdrCaseSpec 180 + ) -> None: 181 + """Emit encoder for an XDR union's arm (data only, no case/break)""" 182 + 183 + if isinstance(node.arm, _XdrVoid): 184 + return 185 + if isinstance(node.arm, _XdrString): 186 + type_name = "char *" 187 + else: 188 + type_name = node.arm.spec.type_name 189 + 190 + assert isinstance(node.arm, (_XdrBasic, _XdrString)) 191 + template = get_jinja2_template(environment, "encoder", node.arm.template) 192 + print( 193 + template.render( 194 + name=node.arm.name, 195 + type=type_name, 196 + ) 197 + ) 215 198 216 199 217 200 def emit_union_case_spec_encoder( ··· 296 235 template = get_jinja2_template(environment, "encoder", "open") 297 236 print(template.render(name=node.name)) 298 237 299 - emit_union_switch_spec_encoder(environment, node.discriminant) 238 + # For boolean discriminants, use if statement instead of switch 239 + if node.discriminant.spec.type_name == "bool": 240 + template = get_jinja2_template(environment, "encoder", "bool_spec") 241 + print(template.render(name=node.discriminant.name, type=node.discriminant.spec.type_name)) 300 242 301 - for case in node.cases: 302 - emit_union_case_spec_encoder( 303 - environment, 304 - case, 305 - node.discriminant.spec.type_name in big_endian, 306 - ) 243 + # Find and emit the TRUE case 244 + for case in node.cases: 245 + if case.values and case.values[0] == "TRUE": 246 + emit_union_arm_encoder(environment, case) 247 + break 307 248 308 - emit_union_default_spec_encoder(environment, node) 249 + template = get_jinja2_template(environment, "encoder", "close") 250 + print(template.render()) 251 + else: 252 + emit_union_switch_spec_encoder(environment, node.discriminant) 309 253 310 - template = get_jinja2_template(environment, "encoder", "close") 311 - print(template.render()) 254 + for case in node.cases: 255 + emit_union_case_spec_encoder( 256 + environment, 257 + case, 258 + node.discriminant.spec.type_name in big_endian, 259 + ) 260 + 261 + emit_union_default_spec_encoder(environment, node) 262 + 263 + template = get_jinja2_template(environment, "encoder", "close") 264 + print(template.render()) 312 265 313 266 314 267 def emit_union_maxsize(environment: Environment, node: _XdrUnion) -> None:
+7
tools/net/sunrpc/xdrgen/templates/C/union/decoder/bool_spec.j2
··· 1 + {# SPDX-License-Identifier: GPL-2.0 #} 2 + {% if annotate %} 3 + /* discriminant {{ name }} */ 4 + {% endif %} 5 + if (!xdrgen_decode_{{ type }}(xdr, &ptr->{{ name }})) 6 + return false; 7 + if (ptr->{{ name }}) {
+7
tools/net/sunrpc/xdrgen/templates/C/union/encoder/bool_spec.j2
··· 1 + {# SPDX-License-Identifier: GPL-2.0 #} 2 + {% if annotate %} 3 + /* discriminant {{ name }} */ 4 + {% endif %} 5 + if (!xdrgen_encode_{{ type }}(xdr, ptr->{{ name }})) 6 + return false; 7 + if (ptr->{{ name }}) {