kconfig: do not reparent the menu inside a choice block
authorMasahiro Yamada <masahiroy@kernel.org>
Sat, 23 Mar 2024 08:51:01 +0000 (17:51 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Thu, 28 Mar 2024 02:02:13 +0000 (11:02 +0900)
commit7e3465f63a0a70641ed8e49f9d40ee613f7da586
tree9923298f87f3020a3f7b67e06cad2ea024a1c64e
parent9a88b338d6e941bd89bcbcbe9b834ebe896fea4a
kconfig: do not reparent the menu inside a choice block

The boolean 'choice' is used to list exclusively selected config
options.

You must not add a dependency between choice members, because such a
dependency would create an invisible entry.

In the following test case, it is impossible to choose 'C'.

[Test Case 1]

  choice
          prompt "Choose one, but how to choose C?"

  config A
          bool "A"

  config B
          bool "B"

  config C
          bool "C"
          depends on A

  endchoice

Hence, Kconfig shows the following error message:

  Kconfig:1:error: recursive dependency detected!
  Kconfig:1:      choice <choice> contains symbol C
  Kconfig:10:     symbol C is part of choice A
  Kconfig:4:      symbol A is part of choice <choice>
  For a resolution refer to Documentation/kbuild/kconfig-language.rst
  subsection "Kconfig recursive dependency limitations"

However, Kconfig does not report anything for the following similar code:

[Test Case 2]

  choice
         prompt "Choose one, but how to choose B?"

  config A
          bool "A"

  config B
          bool "B"
          depends on A

  config C
          bool "C"

  endchoice

This is because menu_finalize() reparents the menu tree when an entry
depends on the preceding one.

With reparenting, the menu tree:

  choice
   |- A
   |- B
   \- C

... will be transformed into the following structure:

  choice
   |- A
   |  \- B
   \- C

Consequently, Kconfig considers only 'A' and 'C' as choice members.
This behavior is awkward. The second test case should be an error too.

This commit stops reparenting inside a choice.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
scripts/kconfig/conf.c
scripts/kconfig/lkc.h
scripts/kconfig/menu.c
scripts/kconfig/parser.y