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.

genksyms: fix last 3 shift/reduce conflicts

The genksyms parser has ambiguities in its grammar, which are currently
suppressed by a workaround in scripts/genksyms/Makefile.

Building genksyms with W=1 generates the following warnings:

YACC scripts/genksyms/parse.tab.[ch]
scripts/genksyms/parse.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
scripts/genksyms/parse.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples

The ambiguity arises when decl_specifier_seq is followed by '(' because
the following two interpretations are possible:

- decl_specifier_seq direct_abstract_declarator '(' parameter_declaration_clause ')'
- decl_specifier_seq '(' abstract_declarator ')'

This issue occurs because the current parser allows an empty string to
be reduced to direct_abstract_declarator, which is incorrect.

K&R [1] explains the correct grammar:

<parameter-declaration> ::= {<declaration-specifier>}+ <declarator>
| {<declaration-specifier>}+ <abstract-declarator>
| {<declaration-specifier>}+

<abstract-declarator> ::= <pointer>
| <pointer> <direct-abstract-declarator>
| <direct-abstract-declarator>

<direct-abstract-declarator> ::= ( <abstract-declarator> )
| {<direct-abstract-declarator>}? [ {<constant-expression>}? ]
| {<direct-abstract-declarator>}? ( {<parameter-type-list>}? )

This commit resolves all remaining conflicts.

We need to consider the difference between the following two examples:

[Example 1] ( <abstract-declarator> ) can become <direct-abstract-declarator>

void my_func(int (foo));

... is equivalent to:

void my_func(int foo);

[Example 2] ( <parameter-type-list> ) can become <direct-abstract-declarator>

typedef int foo;
void my_func(int (foo));

... is equivalent to:

void my_func(int (*callback)(int));

Please note that the function declaration is identical in both examples,
but the preceding typedef creates the distinction. I introduced a new
term, open_paren, to enable the type lookup immediately after the '('
token. Without this, we cannot distinguish between [Example 1] and
[Example 2].

[1]: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Acked-by: Nicolas Schier <n.schier@avm.de>

+20 -8
+20 -8
scripts/genksyms/parse.y
··· 363 363 ; 364 364 365 365 parameter_declaration: 366 - decl_specifier_seq abstract_declarator 366 + decl_specifier_seq abstract_declarator_opt 367 367 { $$ = $2 ? $2 : $1; } 368 368 ; 369 369 370 + abstract_declarator_opt: 371 + /* empty */ { $$ = NULL; } 372 + | abstract_declarator 373 + ; 374 + 370 375 abstract_declarator: 371 - ptr_operator abstract_declarator 376 + ptr_operator 377 + | ptr_operator abstract_declarator 372 378 { $$ = $2 ? $2 : $1; } 373 379 | direct_abstract_declarator 374 380 { $$ = $1; dont_want_type_specifier = false; } 375 381 ; 376 382 377 383 direct_abstract_declarator: 378 - /* empty */ { $$ = NULL; } 379 - | IDENT 384 + IDENT 380 385 { /* For version 2 checksums, we don't want to remember 381 386 private parameter names. */ 382 387 remove_node($1); 383 388 $$ = $1; 384 389 } 385 - | direct_abstract_declarator '(' parameter_declaration_clause ')' 390 + | direct_abstract_declarator open_paren parameter_declaration_clause ')' 386 391 { $$ = $4; } 387 - | direct_abstract_declarator '(' error ')' 392 + | direct_abstract_declarator open_paren error ')' 388 393 { $$ = $4; } 389 394 | direct_abstract_declarator BRACKET_PHRASE 390 395 { $$ = $2; } 391 - | '(' abstract_declarator ')' 396 + | open_paren parameter_declaration_clause ')' 392 397 { $$ = $3; } 393 - | '(' error ')' 398 + | open_paren abstract_declarator ')' 394 399 { $$ = $3; } 400 + | open_paren error ')' 401 + { $$ = $3; } 402 + | BRACKET_PHRASE 403 + ; 404 + 405 + open_paren: 406 + '(' { $$ = $1; dont_want_type_specifier = false; } 395 407 ; 396 408 397 409 function_definition: