diff mbox

[v2] sparse: Make -Werror turn warnigns into errors

Message ID 795aaa7448d91bd59bcbea3d8e49b068a569409e.1411632579.git.tgraf@suug.ch (mailing list archive)
State Mainlined, archived
Headers show

Commit Message

Thomas Graf Sept. 25, 2014, 8:11 a.m. UTC
Make sparse fail and return an error code if a warning is encountered
and -Werror is specified or a hard error is found. This allows to use
sparse in automated build systems to more easily catch new sparse
warnings.

The validation script is extended to parse the expected output message
for an error message and validate the a non zero return value if such
a error message is found.

Also changes cgcc to die if the checker fails.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
v2:
 - Detect non zero return value via expected output in validation script
   as suggested by Christopher Li <sparse@chrisli.org>.

 cgcc                  |  2 +-
 lib.c                 | 49 ++++++++++++++++++++++++++++++-------------------
 lib.h                 |  1 +
 sparse.1              |  3 +++
 sparse.c              |  3 +++
 validation/test-suite | 18 ++++++++++++------
 6 files changed, 50 insertions(+), 26 deletions(-)

Comments

Dan Carpenter Oct. 7, 2014, 9:45 a.m. UTC | #1
> diff --git a/cgcc b/cgcc
> index c075e5f..204bda3 100755
> --- a/cgcc
> +++ b/cgcc
> @@ -70,7 +70,7 @@ if ($do_check) {
>  
>      print "$check\n" if $verbose;
>      if ($do_compile) {
> -	system ($check);
> +	system ($check) == 0 or die;

This just enables -Werror for everyone so now I can't run Sparse on
itself now because there are old errors from 2007.

lib.c:192:6: error: symbol 'error_die' redeclared with different type (originally declared at lib.h:97) - different modifiers
lib.c:201:6: error: symbol 'die' redeclared with different type (originally declared at lib.h:93) - different modifiers

Btw, these errors also disable warnings for the rest of the file...  I
don't think just because there are different modifiers it means that
we should give up looking for other warnings.  In the kernel we miss
some endian bugs because of this.

regards,
dan carpenter

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thomas Graf Oct. 8, 2014, 9:39 a.m. UTC | #2
On 10/07/14 at 12:45pm, Dan Carpenter wrote:
> > diff --git a/cgcc b/cgcc
> > index c075e5f..204bda3 100755
> > --- a/cgcc
> > +++ b/cgcc
> > @@ -70,7 +70,7 @@ if ($do_check) {
> >  
> >      print "$check\n" if $verbose;
> >      if ($do_compile) {
> > -	system ($check);
> > +	system ($check) == 0 or die;
> 
> This just enables -Werror for everyone so now I can't run Sparse on
> itself now because there are old errors from 2007.

The above change should merely have sparse fail upon an error and not
warnings unless you specifiy -Werror which I would consider expected
behaviour.

> lib.c:192:6: error: symbol 'error_die' redeclared with different type (originally declared at lib.h:97) - different modifiers
> lib.c:201:6: error: symbol 'die' redeclared with different type (originally declared at lib.h:93) - different modifiers
> 
> Btw, these errors also disable warnings for the rest of the file...  I
> don't think just because there are different modifiers it means that
> we should give up looking for other warnings.  In the kernel we miss
> some endian bugs because of this.


--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christopher Li Oct. 8, 2014, 10:26 a.m. UTC | #3
On Tue, Oct 7, 2014 at 5:45 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
>> +     system ($check) == 0 or die;
>
> This just enables -Werror for everyone so now I can't run Sparse on
> itself now because there are old errors from 2007.
>
> lib.c:192:6: error: symbol 'error_die' redeclared with different type (originally declared at lib.h:97) - different modifiers
> lib.c:201:6: error: symbol 'die' redeclared with different type (originally declared at lib.h:93) - different modifiers

It depend on how you invoke sparse.
Do you invoke sparse by some thing like "make CC=./cgcc"?

>
> Btw, these errors also disable warnings for the rest of the file...  I
> don't think just because there are different modifiers it means that
> we should give up looking for other warnings.  In the kernel we miss
> some endian bugs because of this.

Are you suggesting change that type different error into warnings so
sparse can still check the rest of the file?

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dan Carpenter Oct. 8, 2014, 7:27 p.m. UTC | #4
On Wed, Oct 08, 2014 at 06:26:23PM +0800, Christopher Li wrote:
> On Tue, Oct 7, 2014 at 5:45 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> >> +     system ($check) == 0 or die;
> >
> > This just enables -Werror for everyone so now I can't run Sparse on
> > itself now because there are old errors from 2007.
> >
> > lib.c:192:6: error: symbol 'error_die' redeclared with different type (originally declared at lib.h:97) - different modifiers
> > lib.c:201:6: error: symbol 'die' redeclared with different type (originally declared at lib.h:93) - different modifiers
> 
> It depend on how you invoke sparse.
> Do you invoke sparse by some thing like "make CC=./cgcc"?

Yes.  In my makefile I have:

ifeq ($(CC),"")
CC = gcc
endif

> 
> >
> > Btw, these errors also disable warnings for the rest of the file...  I
> > don't think just because there are different modifiers it means that
> > we should give up looking for other warnings.  In the kernel we miss
> > some endian bugs because of this.
> 
> Are you suggesting change that type different error into warnings so
> sparse can still check the rest of the file?

Let me look at this more closely again and write some patches.

regards,
dan carpenter

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/cgcc b/cgcc
index c075e5f..204bda3 100755
--- a/cgcc
+++ b/cgcc
@@ -70,7 +70,7 @@  if ($do_check) {
 
     print "$check\n" if $verbose;
     if ($do_compile) {
-	system ($check);
+	system ($check) == 0 or die;
     } else {
 	exec ($check);
     }
diff --git a/lib.c b/lib.c
index 4e6fc81..5203d98 100644
--- a/lib.c
+++ b/lib.c
@@ -126,25 +126,6 @@  void info(struct position pos, const char * fmt, ...)
 	va_end(args);
 }
 
-void warning(struct position pos, const char * fmt, ...)
-{
-	va_list args;
-
-	if (!max_warnings) {
-		show_info = 0;
-		return;
-	}
-
-	if (!--max_warnings) {
-		show_info = 0;
-		fmt = "too many warnings";
-	}
-
-	va_start(args, fmt);
-	do_warn("warning: ", pos, fmt, args);
-	va_end(args);
-}	
-
 static void do_error(struct position pos, const char * fmt, va_list args)
 {
 	static int errors = 0;
@@ -165,6 +146,32 @@  static void do_error(struct position pos, const char * fmt, va_list args)
 	errors++;
 }	
 
+void warning(struct position pos, const char * fmt, ...)
+{
+	va_list args;
+
+	if (Werror) {
+		va_start(args, fmt);
+		do_error(pos, fmt, args);
+		va_end(args);
+		return;
+	}
+
+	if (!max_warnings) {
+		show_info = 0;
+		return;
+	}
+
+	if (!--max_warnings) {
+		show_info = 0;
+		fmt = "too many warnings";
+	}
+
+	va_start(args, fmt);
+	do_warn("warning: ", pos, fmt, args);
+	va_end(args);
+}
+
 void sparse_error(struct position pos, const char * fmt, ...)
 {
 	va_list args;
@@ -219,6 +226,7 @@  int Wdesignated_init = 1;
 int Wdo_while = 0;
 int Winit_cstring = 0;
 int Wenum_mismatch = 1;
+int Werror = 0;
 int Wnon_pointer_null = 1;
 int Wold_initializer = 1;
 int Wone_bit_signed_bitfield = 1;
@@ -467,6 +475,9 @@  static char **handle_onoff_switch(char *arg, char **next, const struct warning w
 		}
 	}
 
+	if (!strcmp(p, "error"))
+		Werror = 1;
+
 	// Prefixes "no" and "no-" mean to turn warning off.
 	if (p[0] == 'n' && p[1] == 'o') {
 		p += 2;
diff --git a/lib.h b/lib.h
index f6cd9b4..dc01684 100644
--- a/lib.h
+++ b/lib.h
@@ -112,6 +112,7 @@  extern int Wdefault_bitfield_sign;
 extern int Wdesignated_init;
 extern int Wdo_while;
 extern int Wenum_mismatch;
+extern int Werror;
 extern int Winit_cstring;
 extern int Wnon_pointer_null;
 extern int Wold_initializer;
diff --git a/sparse.1 b/sparse.1
index 54da09b..acdce53 100644
--- a/sparse.1
+++ b/sparse.1
@@ -24,6 +24,9 @@  off those warnings, pass the negation of the associated warning option,
 Turn on all sparse warnings, except for those explicitly disabled via
 \fB\-Wno\-something\fR.
 .TP
+.B \-Werror
+Turn all sparse warnings into errors.
+.TP
 .B \-Waddress\-space
 Warn about code which mixes pointers to different address spaces.
 
diff --git a/sparse.c b/sparse.c
index 233585b..7d389b1 100644
--- a/sparse.c
+++ b/sparse.c
@@ -287,6 +287,9 @@  static void check_symbols(struct symbol_list *list)
 			check_context(ep);
 		}
 	} END_FOR_EACH_PTR(sym);
+
+	if (die_if_error)
+		exit(1);
 }
 
 int main(int argc, char **argv)
diff --git a/validation/test-suite b/validation/test-suite
index 3c011c6..61667a5 100755
--- a/validation/test-suite
+++ b/validation/test-suite
@@ -106,20 +106,26 @@  do_test()
 	fi
 	verbose "Using command       : $cmd"
 
+	# grab the expected output
+	sed -n '/check-output-start/,/check-output-end/p' $file \
+		| grep -v check-output > "$file".output.expected
+	sed -n '/check-error-start/,/check-error-end/p' $file \
+		| grep -v check-error > "$file".error.expected
+
 	# grab the expected exit value
 	get_value "check-exit-value" $file
 	if [ "$?" -eq "0" ]; then
 		expected_exit_value=`echo $last_result | tr -d ' '`
 	else
-		expected_exit_value=0
+		grep -q -E "^[^:]+:[[:digit:]]+:[[:digit:]]+: error:" "$file".error.expected
+		if  [ "$?" -eq "0" ]; then
+			expected_exit_value=1
+		else
+			expected_exit_value=0
+		fi
 	fi
 	verbose "Expecting exit value: $expected_exit_value"
 
-	# grab the expected output
-	sed -n '/check-output-start/,/check-output-end/p' $file \
-		| grep -v check-output > "$file".output.expected
-	sed -n '/check-error-start/,/check-error-end/p' $file \
-		| grep -v check-error > "$file".error.expected
 
 	# grab the actual output & exit value
 	$cmd 1> $file.output.got 2> $file.error.got