kconfig: do not write choice values when their dependency becomes n

"# CONFIG_... is not set" for choice values are wrongly written into
the .config file if they are once visible, then become invisible later.

  Test case
  ---------

---------------------------(Kconfig)----------------------------
config A
	bool "A"

choice
	prompt "Choice ?"
	depends on A

config CHOICE_B
	bool "Choice B"

config CHOICE_C
	bool "Choice C"

endchoice
----------------------------------------------------------------

---------------------------(.config)----------------------------
CONFIG_A=y
----------------------------------------------------------------

With the Kconfig and .config above,

  $ make config
  scripts/kconfig/conf  --oldaskconfig Kconfig
  *
  * Linux Kernel Configuration
  *
  A (A) [Y/n] n
  #
  # configuration written to .config
  #
  $ cat .config
  #
  # Automatically generated file; DO NOT EDIT.
  # Linux Kernel Configuration
  #
  # CONFIG_A is not set
  # CONFIG_CHOICE_B is not set
  # CONFIG_CHOICE_C is not set

Here,

  # CONFIG_CHOICE_B is not set
  # CONFIG_CHOICE_C is not set

should not be written into the .config file because their dependency
"depends on A" is unmet.

Currently, there is no code that clears SYMBOL_WRITE of choice values.

Clear SYMBOL_WRITE for all symbols in sym_calc_value(), then set it
again after calculating visibility.  To simplify the logic, set the
flag if they have non-n visibility, regardless of types, and regardless
of whether they are choice values or not.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Ulf Magnusson <ulfalizer@gmail.com>
This commit is contained in:
Masahiro Yamada 2018-02-06 09:34:42 +09:00
parent a2b0fe7435
commit cb67ab2cd2

View File

@ -371,11 +371,13 @@ void sym_calc_value(struct symbol *sym)
sym->curr.tri = no; sym->curr.tri = no;
return; return;
} }
if (!sym_is_choice_value(sym)) sym->flags &= ~SYMBOL_WRITE;
sym->flags &= ~SYMBOL_WRITE;
sym_calc_visibility(sym); sym_calc_visibility(sym);
if (sym->visible != no)
sym->flags |= SYMBOL_WRITE;
/* set default if recursively called */ /* set default if recursively called */
sym->curr = newval; sym->curr = newval;
@ -390,7 +392,6 @@ void sym_calc_value(struct symbol *sym)
/* if the symbol is visible use the user value /* if the symbol is visible use the user value
* if available, otherwise try the default value * if available, otherwise try the default value
*/ */
sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) { if (sym_has_value(sym)) {
newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
sym->visible); sym->visible);
@ -433,12 +434,9 @@ void sym_calc_value(struct symbol *sym)
case S_STRING: case S_STRING:
case S_HEX: case S_HEX:
case S_INT: case S_INT:
if (sym->visible != no) { if (sym->visible != no && sym_has_value(sym)) {
sym->flags |= SYMBOL_WRITE; newval.val = sym->def[S_DEF_USER].val;
if (sym_has_value(sym)) { break;
newval.val = sym->def[S_DEF_USER].val;
break;
}
} }
prop = sym_get_default_prop(sym); prop = sym_get_default_prop(sym);
if (prop) { if (prop) {