util/lint/kconfig_lint: Add 3 new checks
- Check that selected symbols are type bool - Check that selected symbols aren't created inside a choice - Check that symbols created inside a choice aren't created outside of a choice as well. Change-Id: I08963d637f8bdfb2413cfe831eafdc974d7674ab Signed-off-by: Martin Roth <martinroth@google.com> Reviewed-on: https://review.coreboot.org/12969 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
		@@ -50,6 +50,7 @@ my %symbols;               # main structure of all symbols declared
 | 
				
			|||||||
my %referenced_symbols;    # list of symbols referenced by expressions or select statements
 | 
					my %referenced_symbols;    # list of symbols referenced by expressions or select statements
 | 
				
			||||||
my %used_symbols;          # structure of symbols used in the tree, and where they're found
 | 
					my %used_symbols;          # structure of symbols used in the tree, and where they're found
 | 
				
			||||||
my @collected_symbols;     #
 | 
					my @collected_symbols;     #
 | 
				
			||||||
 | 
					my %selected_symbols;      # list of symbols that are enabled by a select statement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Main();
 | 
					Main();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -87,6 +88,7 @@ sub Main {
 | 
				
			|||||||
    check_for_ifdef();
 | 
					    check_for_ifdef();
 | 
				
			||||||
    check_for_def();
 | 
					    check_for_def();
 | 
				
			||||||
    check_is_enabled();
 | 
					    check_is_enabled();
 | 
				
			||||||
 | 
					    check_selected_symbols();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    print_wholeconfig();
 | 
					    print_wholeconfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -123,6 +125,48 @@ sub show_warning {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# check selected symbols for validity
 | 
				
			||||||
 | 
					# they must be bools
 | 
				
			||||||
 | 
					# they cannot select symbols created in 'choice' blocks
 | 
				
			||||||
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					sub check_selected_symbols {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #loop through symbols found in expressions and used by 'select' keywords
 | 
				
			||||||
 | 
					    foreach my $symbol ( sort ( keys %selected_symbols ) ) {
 | 
				
			||||||
 | 
					        my $type_failure   = 0;
 | 
				
			||||||
 | 
					        my $choice_failure = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #errors selecting symbols that don't exist are already printed, so we
 | 
				
			||||||
 | 
					        #don't need to print them again here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #make sure the selected symbols are bools
 | 
				
			||||||
 | 
					        if ( ( exists $symbols{$symbol} ) && ( $symbols{$symbol}{type} ne "bool" ) ) {
 | 
				
			||||||
 | 
					            $type_failure = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #make sure we're not selecting choice symbols
 | 
				
			||||||
 | 
					        if ( ( exists $symbols{$symbol} ) && ( $symbols{$symbol}{choice} ) ) {
 | 
				
			||||||
 | 
					            $choice_failure = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #loop through each instance of the symbol to print out all of the failures
 | 
				
			||||||
 | 
					        for ( my $i = 0 ; $i <= $referenced_symbols{$symbol}{count} ; $i++ ) {
 | 
				
			||||||
 | 
					            next if ( !exists $selected_symbols{$symbol}{$i} );
 | 
				
			||||||
 | 
					            my $file   = $referenced_symbols{$symbol}{$i}{filename};
 | 
				
			||||||
 | 
					            my $lineno = $referenced_symbols{$symbol}{$i}{line_no};
 | 
				
			||||||
 | 
					            if ($type_failure) {
 | 
				
			||||||
 | 
					                show_error(
 | 
				
			||||||
 | 
					                    "CONFIG_$symbol' selected at $file:$lineno." . "  Selects only work on symbols of type bool." );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($choice_failure) {
 | 
				
			||||||
 | 
					                show_error(
 | 
				
			||||||
 | 
					                    "'CONFIG_$symbol' selected at $file:$lineno." . "  Symbols created in a choice cannot be selected." );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#-------------------------------------------------------------------------------
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
# check_for_ifdef - Look for instances of #ifdef CONFIG_[symbol_name] and
 | 
					# check_for_ifdef - Look for instances of #ifdef CONFIG_[symbol_name] and
 | 
				
			||||||
# #if defined(CONFIG_[symbol_name]).
 | 
					# #if defined(CONFIG_[symbol_name]).
 | 
				
			||||||
@@ -406,7 +450,7 @@ sub build_and_parse_kconfig_tree {
 | 
				
			|||||||
            if ($inside_choice) {
 | 
					            if ($inside_choice) {
 | 
				
			||||||
                $configs_inside_choice++;
 | 
					                $configs_inside_choice++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            add_symbol( $symbol, \@inside_menu, $filename, $line_no, \@inside_if );
 | 
					            add_symbol( $symbol, \@inside_menu, $filename, $line_no, \@inside_if, $inside_choice );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #bool|hex|int|string|tristate <expr> [if <expr>]
 | 
					        #bool|hex|int|string|tristate <expr> [if <expr>]
 | 
				
			||||||
@@ -548,7 +592,7 @@ sub build_and_parse_kconfig_tree {
 | 
				
			|||||||
                my $expression;
 | 
					                my $expression;
 | 
				
			||||||
                ( $line, $expression ) = handle_if_line( $line, $inside_config, $filename, $line_no );
 | 
					                ( $line, $expression ) = handle_if_line( $line, $inside_config, $filename, $line_no );
 | 
				
			||||||
                if ($line) {
 | 
					                if ($line) {
 | 
				
			||||||
                    add_referenced_symbol( $line, $filename, $line_no );
 | 
					                    add_referenced_symbol( $line, $filename, $line_no, 'select' );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -596,17 +640,33 @@ sub handle_depends {
 | 
				
			|||||||
#-------------------------------------------------------------------------------
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
#-------------------------------------------------------------------------------
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
sub add_symbol {
 | 
					sub add_symbol {
 | 
				
			||||||
    my ( $symbol, $menu_array_ref, $filename, $line_no, $ifref ) = @_;
 | 
					    my ( $symbol, $menu_array_ref, $filename, $line_no, $ifref, $inside_choice ) = @_;
 | 
				
			||||||
    my @inside_if = @{$ifref};
 | 
					    my @inside_if = @{$ifref};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #initialize the symbol or increment the use count.
 | 
					    #initialize the symbol or increment the use count.
 | 
				
			||||||
    if ( ( !exists $symbols{$symbol} ) || ( !exists $symbols{$symbol}{count} ) ) {
 | 
					    if ( ( !exists $symbols{$symbol} ) || ( !exists $symbols{$symbol}{count} ) ) {
 | 
				
			||||||
        $symbols{$symbol}{count} = 0;
 | 
					        $symbols{$symbol}{count} = 0;
 | 
				
			||||||
 | 
					        if ($inside_choice) {
 | 
				
			||||||
 | 
					            $symbols{$symbol}{choice} = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            $symbols{$symbol}{choice} = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        $symbols{$symbol}{count}++;
 | 
					        $symbols{$symbol}{count}++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ( $inside_choice && !$symbols{$symbol}{choice} ) {
 | 
				
			||||||
 | 
					            show_error( "$symbol entry at $filename:$line_no has already been created inside a choice block "
 | 
				
			||||||
 | 
					                  . "at $symbols{$symbol}{0}{file}:$symbols{$symbol}{0}{line_no}." );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        elsif ( !$inside_choice && $symbols{$symbol}{choice} ) {
 | 
				
			||||||
 | 
					            show_error( "$symbol entry at $filename:$line_no has already been created outside a choice block "
 | 
				
			||||||
 | 
					                  . "at $symbols{$symbol}{0}{file}:$symbols{$symbol}{0}{line_no}." );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # add the location of this instance
 | 
					    # add the location of this instance
 | 
				
			||||||
    my $symcount = $symbols{$symbol}{count};
 | 
					    my $symcount = $symbols{$symbol}{count};
 | 
				
			||||||
    $symbols{$symbol}{$symcount}{file}    = $filename;
 | 
					    $symbols{$symbol}{$symcount}{file}    = $filename;
 | 
				
			||||||
@@ -755,7 +815,7 @@ sub handle_expressions {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ( $exprline =~ /^\s*([A-Za-z0-9_]+)\s*$/ ) {                   # <symbol>                             (1)
 | 
					    elsif ( $exprline =~ /^\s*([A-Za-z0-9_]+)\s*$/ ) {                   # <symbol>                             (1)
 | 
				
			||||||
        add_referenced_symbol( $1, $filename, $line_no );
 | 
					        add_referenced_symbol( $1, $filename, $line_no, 'expression' );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ( $exprline =~ /^\s*!(.+)$/ ) {                                # '!' <expr>                           (5)
 | 
					    elsif ( $exprline =~ /^\s*!(.+)$/ ) {                                # '!' <expr>                           (5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -796,7 +856,7 @@ sub handle_expressions {
 | 
				
			|||||||
# add_referenced_symbol
 | 
					# add_referenced_symbol
 | 
				
			||||||
#-------------------------------------------------------------------------------
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
sub add_referenced_symbol {
 | 
					sub add_referenced_symbol {
 | 
				
			||||||
    my ( $symbol, $filename, $line_no ) = @_;
 | 
					    my ( $symbol, $filename, $line_no, $reftype ) = @_;
 | 
				
			||||||
    if ( exists $referenced_symbols{$symbol} ) {
 | 
					    if ( exists $referenced_symbols{$symbol} ) {
 | 
				
			||||||
        $referenced_symbols{$symbol}{count}++;
 | 
					        $referenced_symbols{$symbol}{count}++;
 | 
				
			||||||
        $referenced_symbols{$symbol}{ $referenced_symbols{$symbol}{count} }{filename} = $filename;
 | 
					        $referenced_symbols{$symbol}{ $referenced_symbols{$symbol}{count} }{filename} = $filename;
 | 
				
			||||||
@@ -807,6 +867,11 @@ sub add_referenced_symbol {
 | 
				
			|||||||
        $referenced_symbols{$symbol}{0}{filename} = $filename;
 | 
					        $referenced_symbols{$symbol}{0}{filename} = $filename;
 | 
				
			||||||
        $referenced_symbols{$symbol}{0}{line_no}  = $line_no;
 | 
					        $referenced_symbols{$symbol}{0}{line_no}  = $line_no;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #mark the symbol as being selected, use referenced symbols for location
 | 
				
			||||||
 | 
					    if ( $reftype eq 'select' ) {
 | 
				
			||||||
 | 
					        $selected_symbols{$symbol}{ $referenced_symbols{$symbol}{count} } = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#-------------------------------------------------------------------------------
 | 
					#-------------------------------------------------------------------------------
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user