kconfig: report recursive dependency involving 'imply'
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Wed, 15 Aug 2018 05:59:44 +0000 (14:59 +0900)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Wed, 22 Aug 2018 14:21:39 +0000 (23:21 +0900)
Currently, Kconfig does not complain about the recursive dependency
where 'imply' keywords are involved.

[Test Code]

  config A
          bool "a"

  config B
          bool "b"
          imply A
          depends on A

In the code above, Kconfig cannot calculate the symbol values correctly
due to the circular dependency.  For example, allyesconfig followed by
syncconfig results in an odd behavior because CONFIG_B becomes visible
in syncconfig.

  $ make allyesconfig
  scripts/kconfig/conf  --allyesconfig Kconfig
  #
  # configuration written to .config
  #
  $ cat .config
  #
  # Automatically generated file; DO NOT EDIT.
  # Main menu
  #
  CONFIG_A=y
  $ make syncconfig
  scripts/kconfig/conf  --syncconfig Kconfig
  *
  * Restart config...
  *
  *
  * Main menu
  *
  a (A) [Y/n/?] y
    b (B) [N/y/?] (NEW)

To detect this correctly, sym_check_expr_deps() should recurse to
not only sym->rev_dep.expr but also sym->implied.expr .

At this moment, sym_check_print_recursive() cannot distinguish
'select' and 'imply' since it does not know the precise context
where the recursive dependency has been hit.  This will be solved
by the next commit.

In fact, even the document and the unit-test are confused.  Using
'imply' does not solve recursive dependency since 'imply' addresses
the unmet direct dependency, which 'select' could cause.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Dirk Gouders <dirk@gouders.net>
Documentation/kbuild/kconfig-language.txt
scripts/kconfig/symbol.c
scripts/kconfig/tests/err_recursive_dep/Kconfig
scripts/kconfig/tests/err_recursive_dep/expected_stderr

index c54cb7cb9ff45fc49189161bc80d3586f0e91586..864e740811dadab3c8f7dafb4a240656a9e9d0bf 100644 (file)
@@ -545,7 +545,7 @@ make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
 Practical solutions to kconfig recursive issue
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Developers who run into the recursive Kconfig issue have three options
+Developers who run into the recursive Kconfig issue have two options
 at their disposal. We document them below and also provide a list of
 historical issues resolved through these different solutions.
 
@@ -553,7 +553,6 @@ historical issues resolved through these different solutions.
   b) Match dependency semantics:
        b1) Swap all "select FOO" to "depends on FOO" or,
        b2) Swap all "depends on FOO" to "select FOO"
-  c) Consider the use of "imply" instead of "select"
 
 The resolution to a) can be tested with the sample Kconfig file
 Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
index 688f487ff454e629eb9b83dc7c489c56da38cdc0..90e706096af8221d23a26be37d83678dcfddfe36 100644 (file)
@@ -1098,7 +1098,7 @@ static void sym_check_print_recursive(struct symbol *last_sym)
                                sym->name ? sym->name : "<choice>",
                                next_sym->name ? next_sym->name : "<choice>");
                } else {
-                       fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+                       fprintf(stderr, "%s:%d:\tsymbol %s is selected or implied by %s\n",
                                prop->file->name, prop->lineno,
                                sym->name ? sym->name : "<choice>",
                                next_sym->name ? next_sym->name : "<choice>");
@@ -1161,8 +1161,13 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
        if (sym2)
                goto out;
 
+       sym2 = sym_check_expr_deps(sym->implied.expr);
+       if (sym2)
+               goto out;
+
        for (prop = sym->prop; prop; prop = prop->next) {
-               if (prop->type == P_CHOICE || prop->type == P_SELECT)
+               if (prop->type == P_CHOICE || prop->type == P_SELECT ||
+                   prop->type == P_IMPLY)
                        continue;
                stack.prop = prop;
                sym2 = sym_check_expr_deps(prop->visible.expr);
index a65bfcb7137eea94c9dbb5053673367e4352f00d..ebdb3ffd87170a8b114efa168428bf1e87f9df6b 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 # depends on itself
 
 config A
@@ -31,7 +33,6 @@ config D2
        bool
 
 # depends on and imply
-# This is not recursive dependency
 
 config E1
        bool "E1"
index 3de807dd9cb29111201fff96ad7ea476ab3f5b92..2eb25288db8c52f05907d3fc17997b6e567e85b3 100644 (file)
@@ -1,30 +1,38 @@
-Kconfig:9:error: recursive dependency detected!
-Kconfig:9:     symbol B is selected by B
+Kconfig:11:error: recursive dependency detected!
+Kconfig:11:    symbol B is selected or implied by B
 For a resolution refer to Documentation/kbuild/kconfig-language.txt
 subsection "Kconfig recursive dependency limitations"
 
-Kconfig:3:error: recursive dependency detected!
-Kconfig:3:     symbol A depends on A
+Kconfig:5:error: recursive dependency detected!
+Kconfig:5:     symbol A depends on A
 For a resolution refer to Documentation/kbuild/kconfig-language.txt
 subsection "Kconfig recursive dependency limitations"
 
-Kconfig:15:error: recursive dependency detected!
-Kconfig:15:    symbol C1 depends on C2
-Kconfig:19:    symbol C2 depends on C1
+Kconfig:17:error: recursive dependency detected!
+Kconfig:17:    symbol C1 depends on C2
+Kconfig:21:    symbol C2 depends on C1
 For a resolution refer to Documentation/kbuild/kconfig-language.txt
 subsection "Kconfig recursive dependency limitations"
 
-Kconfig:30:error: recursive dependency detected!
-Kconfig:30:    symbol D2 is selected by D1
-Kconfig:25:    symbol D1 depends on D2
+Kconfig:32:error: recursive dependency detected!
+Kconfig:32:    symbol D2 is selected or implied by D1
+Kconfig:27:    symbol D1 depends on D2
 For a resolution refer to Documentation/kbuild/kconfig-language.txt
 subsection "Kconfig recursive dependency limitations"
 
-Kconfig:59:error: recursive dependency detected!
-Kconfig:59:    symbol G depends on G
+Kconfig:37:error: recursive dependency detected!
+Kconfig:37:    symbol E1 depends on E2
+Kconfig:42:    symbol E2 is selected or implied by E1
 For a resolution refer to Documentation/kbuild/kconfig-language.txt
 subsection "Kconfig recursive dependency limitations"
 
-Kconfig:50:error: recursive dependency detected!
-Kconfig:50:    symbol F2 depends on F1
-Kconfig:48:    symbol F1 default value contains F2
+Kconfig:60:error: recursive dependency detected!
+Kconfig:60:    symbol G depends on G
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:51:error: recursive dependency detected!
+Kconfig:51:    symbol F2 depends on F1
+Kconfig:49:    symbol F1 default value contains F2
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"