Hello community,

here is the log from the commit of package sparse for openSUSE:Factory checked 
in at 2015-01-20 12:26:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sparse (Old)
 and      /work/SRC/openSUSE:Factory/.sparse.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "sparse"

Changes:
--------
--- /work/SRC/openSUSE:Factory/sparse/sparse.changes    2014-05-17 
06:43:34.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.sparse.new/sparse.changes       2015-01-20 
12:26:50.000000000 +0100
@@ -1,0 +2,46 @@
+Wed Jan 14 14:56:18 UTC 2015 - jsl...@suse.com
+
+- update to 20141211
+  * Ptr list sorting should use memmove instead of memcpy
+  * build: allow use of PKG_CONFIG to override pkg-config
+  * compile-i386.c: don't ignore return value of write(2)
+  * parse.c: remove duplicate 'may_alias' ignored_attributes
+  * cgcc: avoid passing a sparse-only option to cc
+  * test-suite: remove bashism to avoid test failures
+  * teach next_designators() use array_element_offset()
+  * cgcc: use $ccom to set $multiarch_dir if not specified
+  * cgcc: use only the cc command to determine $gcc_base_dir
+  * Add support for multiarch system header files
+  * don't run sparse{c,i} tests when sparse-llvm is disabled
+  * Makefile: suppress error message from shell
+  * don't call isdigit/tolower with a char argument
+  * sparse: add 'gnu_inline' to the ignored attributes
+  * Add the __restrict__ keyword
+  * sparse: treat function pointers as pointers to const data
+  * rename -Werror to -Wsparse-error
+  * sparse: Make -Werror turn warnigns into errors
+  * Use LLVM_CONFIG instead of llvm-config in Makefile
+  * sparse-llvm: Fix LLVM 3.5 linker errors
+  * Fix initializers in anonymous structs and unions
+  * Make same_symbol list share the same scope
+  * Fix scoping of extern symbols in block scope
+  * round up the array element size to byte align
+  * sparse: make bits_to_bytes round up instead of down
+  * Minor clean up for option handling
+  * lib.c: skip --param parameters
+  * parse: support c99 [static ...] in abstract array declarators
+  * sparse{i,c}: use LLVM_CONFIG to find llc and lli
+  * build: allow use of LLVM_CONFIG to override llvm-config config script
+  * Fix error at anoymous unions
+  * Add test case for the ioc type check
+  * Add test case for anonymous union initializer
+  * Add test case for extern array
+  * Use any previous initializer to size a symbol
+  * Add warning about duplicate initializers
+  * Support GCC's transparent unions
+  * evaluate: split out implementation of compatible_assignment_types
+  * validation/sizeof-bool: fix broken test case
+  * sparse: Allow override of sizeof(bool) warning
+  * Define __CHAR_BIT__
+
+-------------------------------------------------------------------
@@ -4 +50 @@
-- change Licence to new MIT
+- change License to new MIT

Old:
----
  sparse-20140128.tar.xz

New:
----
  sparse-20141211.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ sparse.spec ++++++
--- /var/tmp/diff_new_pack.aTPqnR/_old  2015-01-20 12:26:51.000000000 +0100
+++ /var/tmp/diff_new_pack.aTPqnR/_new  2015-01-20 12:26:51.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package sparse
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
 Summary:        A semantic parser of source files
 License:        MIT
 Group:          Development/Tools/Building
-Version:        20140128
+Version:        20141211
 Release:        0
 Url:            https://sparse.wiki.kernel.org/index.php/Main_Page
 Source:         sparse-%{version}.tar.xz

++++++ sparse-20140128.tar.xz -> sparse-20141211.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/Makefile new/sparse-20141211/Makefile
--- old/sparse-20140128/Makefile        2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/Makefile        2015-01-14 15:55:41.000000000 +0100
@@ -17,6 +17,7 @@
 LDFLAGS += -g
 LD = gcc
 AR = ar
+PKG_CONFIG = pkg-config
 
 ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS)
 #
@@ -25,18 +26,20 @@
 #     CFLAGS += -O0 -DDEBUG -g3 -gdwarf-2
 #
 
-HAVE_LIBXML:=$(shell pkg-config --exists libxml-2.0 2>/dev/null && echo 'yes')
+HAVE_LIBXML:=$(shell $(PKG_CONFIG) --exists libxml-2.0 2>/dev/null && echo 
'yes')
 HAVE_GCC_DEP:=$(shell touch .gcc-test.c &&                             \
                $(CC) -c -Wp,-MD,.gcc-test.d .gcc-test.c 2>/dev/null && \
                echo 'yes'; rm -f .gcc-test.d .gcc-test.o .gcc-test.c)
-HAVE_GTK2:=$(shell pkg-config --exists gtk+-2.0 2>/dev/null && echo 'yes')
-HAVE_LLVM:=$(shell llvm-config --version >/dev/null 2>&1 && echo 'yes')
-HAVE_LLVM_VERSION:=$(shell llvm-config --version | grep "^[3-9].*" >/dev/null 
2>&1 && echo yes)
-LLVM_VERSION=$(shell llvm-config --version)
+HAVE_GTK2:=$(shell $(PKG_CONFIG) --exists gtk+-2.0 2>/dev/null && echo 'yes')
+LLVM_CONFIG:=llvm-config
+HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes')
 
 GCC_BASE = $(shell $(CC) --print-file-name=)
 BASIC_CFLAGS = -DGCC_BASE=\"$(GCC_BASE)\"
 
+MULTIARCH_TRIPLET = $(shell $(CC) -print-multiarch 2>/dev/null)
+BASIC_CFLAGS += -DMULTIARCH_TRIPLET=\"$(MULTIARCH_TRIPLET)\"
+
 ifeq ($(HAVE_GCC_DEP),yes)
 BASIC_CFLAGS += -Wp,-MD,$(@D)/.$(@F).d
 endif
@@ -58,14 +61,14 @@
 ifeq ($(HAVE_LIBXML),yes)
 PROGRAMS+=c2xml
 INST_PROGRAMS+=c2xml
-c2xml_EXTRA_OBJS = `pkg-config --libs libxml-2.0`
+c2xml_EXTRA_OBJS = `$(PKG_CONFIG) --libs libxml-2.0`
 else
 $(warning Your system does not have libxml, disabling c2xml)
 endif
 
 ifeq ($(HAVE_GTK2),yes)
-GTK2_CFLAGS := $(shell pkg-config --cflags gtk+-2.0)
-GTK2_LIBS := $(shell pkg-config --libs gtk+-2.0)
+GTK2_CFLAGS := $(shell $(PKG_CONFIG) --cflags gtk+-2.0)
+GTK2_LIBS := $(shell $(PKG_CONFIG) --libs gtk+-2.0)
 PROGRAMS += test-inspect
 INST_PROGRAMS += test-inspect
 test-inspect_EXTRA_DEPS := ast-model.o ast-view.o ast-inspect.o
@@ -75,23 +78,24 @@
 $(warning Your system does not have libgtk2, disabling test-inspect)
 endif
 
-ifneq ($(HAVE_LLVM),yes)
-$(warning Your system does not have llvm, disabling sparse-llvm)
-else
-ifneq ($(HAVE_LLVM_VERSION),yes)
-$(warning LLVM 3.0 or later required. Your system has version $(LLVM_VERSION) 
installed.)
-HAVE_LLVM=no
-else
+ifeq ($(HAVE_LLVM),yes)
+LLVM_VERSION:=$(shell $(LLVM_CONFIG) --version)
+ifeq ($(shell expr "$(LLVM_VERSION)" : '[3-9]\.'),2)
 LLVM_PROGS := sparse-llvm
 $(LLVM_PROGS): LD := g++
-LLVM_LDFLAGS := $(shell llvm-config --ldflags)
-LLVM_CFLAGS := $(shell llvm-config --cflags | sed -e "s/-DNDEBUG//g")
-LLVM_LIBS := $(shell llvm-config --libs)
+LLVM_LDFLAGS := $(shell $(LLVM_CONFIG) --ldflags)
+LLVM_CFLAGS := $(shell $(LLVM_CONFIG) --cflags | sed -e "s/-DNDEBUG//g")
+LLVM_LIBS := $(shell $(LLVM_CONFIG) --libs)
+LLVM_LIBS += $(shell $(LLVM_CONFIG) --system-libs 2>/dev/null)
 PROGRAMS += $(LLVM_PROGS)
 INST_PROGRAMS += sparse-llvm sparsec
 sparse-llvm.o: BASIC_CFLAGS += $(LLVM_CFLAGS)
 sparse-llvm_EXTRA_OBJS := $(LLVM_LIBS) $(LLVM_LDFLAGS)
+else
+$(warning LLVM 3.0 or later required. Your system has version $(LLVM_VERSION) 
installed.)
 endif
+else
+$(warning Your system does not have llvm, disabling sparse-llvm)
 endif
 
 LIB_H=    token.h parse.h lib.h symbol.h scope.h expression.h target.h \
@@ -184,7 +188,7 @@
 $(if $(DEP_FILES),$(eval include $(DEP_FILES)))
 
 c2xml.o: c2xml.c $(LIB_H)
-       $(QUIET_CC)$(CC) `pkg-config --cflags libxml-2.0` -o $@ -c 
$(ALL_CFLAGS) $<
+       $(QUIET_CC)$(CC) `$(PKG_CONFIG) --cflags libxml-2.0` -o $@ -c 
$(ALL_CFLAGS) $<
 
 compat-linux.o: compat/strtold.c compat/mmap-blob.c $(LIB_H)
 compat-solaris.o: compat/mmap-blob.c $(LIB_H)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/cgcc new/sparse-20141211/cgcc
--- old/sparse-20140128/cgcc    2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/cgcc    2015-01-14 15:55:41.000000000 +0100
@@ -3,6 +3,7 @@
 
 my $cc = $ENV{'REAL_CC'} || 'cc';
 my $check = $ENV{'CHECK'} || 'sparse';
+my $ccom = $cc;
 
 my $m32 = 0;
 my $m64 = 0;
@@ -11,6 +12,7 @@
 my $do_check = 0;
 my $do_compile = 1;
 my $gcc_base_dir;
+my $multiarch_dir;
 my $verbose = 0;
 
 while (@ARGV) {
@@ -44,6 +46,12 @@
         next;
     }
 
+    if (/^-multiarch-dir$/) {
+        $multiarch_dir = shift @ARGV;
+        die ("$0: missing argument for -multiarch-dir option") if 
!$multiarch_dir;
+        next;
+    }
+
     # If someone adds "-E", don't pre-process twice.
     $do_compile = 0 if $_ eq '-E';
 
@@ -65,12 +73,17 @@
        $check .= &add_specs ('host_os_specs');
     }
 
-    $gcc_base_dir = qx($cc -print-file-name=) if !$gcc_base_dir;
+    $gcc_base_dir = qx($ccom -print-file-name=) if !$gcc_base_dir;
+    chomp($gcc_base_dir);  # possibly remove '\n' from compiler
     $check .= " -gcc-base-dir " . $gcc_base_dir if $gcc_base_dir;
 
+    $multiarch_dir = qx($ccom -print-multiarch) if ! defined $multiarch_dir;
+    chomp($multiarch_dir);  # possibly remove '\n' from compiler
+    $check .= " -multiarch-dir " . $multiarch_dir if $multiarch_dir;
+
     print "$check\n" if $verbose;
     if ($do_compile) {
-       system ($check);
+       system ($check) == 0 or exit 1;
     } else {
        exec ($check);
     }
@@ -88,7 +101,7 @@
 
 sub check_only_option {
     my ($arg) = @_;
-    return 1 if $arg =~ 
/^-W(no-?)?(default-bitfield-sign|one-bit-signed-bitfield|cast-truncate|bitwise|typesign|context|undef|ptr-subtraction-blows|cast-to-as|decl|transparent-union|address-space|enum-mismatch|do-while|old-initializer|non-pointer-null|paren-string|return-void|designated-init|sparse-all)$/;
+    return 1 if $arg =~ 
/^-W(no-?)?(default-bitfield-sign|one-bit-signed-bitfield|cast-truncate|bitwise|typesign|context|undef|ptr-subtraction-blows|cast-to-as|decl|transparent-union|address-space|enum-mismatch|do-while|old-initializer|non-pointer-null|paren-string|return-void|designated-init|sparse-all|sparse-error)$/;
     return 1 if $arg =~ /^-v(no-?)?(entry|dead)$/;
     return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/compile-i386.c 
new/sparse-20141211/compile-i386.c
--- old/sparse-20140128/compile-i386.c  2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/compile-i386.c  2015-01-14 15:55:41.000000000 +0100
@@ -732,7 +732,8 @@
                        atom->insn,
                        comment[0] ? "\t\t" : "", comment);
 
-       write(STDOUT_FILENO, s, strlen(s));
+       if (write(STDOUT_FILENO, s, strlen(s)) < 0)
+               die("can't write to stdout");
 }
 
 static void emit_atom_list(struct function *f)
@@ -742,9 +743,8 @@
        FOR_EACH_PTR(f->atom_list, atom) {
                switch (atom->type) {
                case ATOM_TEXT: {
-                       ssize_t rc = write(STDOUT_FILENO, atom->text,
-                                          atom->text_len);
-                       (void) rc;      /* FIXME */
+                       if (write(STDOUT_FILENO, atom->text, atom->text_len) < 
0)
+                               die("can't write to stdout");
                        break;
                }
                case ATOM_INSN:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/evaluate.c 
new/sparse-20141211/evaluate.c
--- old/sparse-20140128/evaluate.c      2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/evaluate.c      2015-01-14 15:55:41.000000000 +0100
@@ -1307,10 +1307,9 @@
        return !Wtypesign;
 }
 
-static int compatible_assignment_types(struct expression *expr, struct symbol 
*target,
-       struct expression **rp, const char *where)
+static int check_assignment_types(struct symbol *target, struct expression 
**rp,
+       const char **typediff)
 {
-       const char *typediff;
        struct symbol *source = degenerate(*rp);
        struct symbol *t, *s;
        int tclass = classify_type(target, &t);
@@ -1327,8 +1326,8 @@
                                return 1;
                } else if (!(sclass & TYPE_RESTRICT))
                        goto Cast;
-               typediff = "different base types";
-               goto Err;
+               *typediff = "different base types";
+               return 0;
        }
 
        if (tclass == TYPE_PTR) {
@@ -1342,8 +1341,8 @@
                        goto Cast;
                }
                if (!(sclass & TYPE_PTR)) {
-                       typediff = "different base types";
-                       goto Err;
+                       *typediff = "different base types";
+                       return 0;
                }
                b1 = examine_pointer_target(t);
                b2 = examine_pointer_target(s);
@@ -1356,19 +1355,28 @@
                         * or mix address spaces [sparse].
                         */
                        if (t->ctype.as != s->ctype.as) {
-                               typediff = "different address spaces";
-                               goto Err;
+                               *typediff = "different address spaces";
+                               return 0;
                        }
+                       /*
+                        * If this is a function pointer assignment, it is
+                        * actually fine to assign a pointer to const data to
+                        * it, as a function pointer points to const data
+                        * implicitly, i.e., dereferencing it does not produce
+                        * an lvalue.
+                        */
+                       if (b1->type == SYM_FN)
+                               mod1 |= MOD_CONST;
                        if (mod2 & ~mod1) {
-                               typediff = "different modifiers";
-                               goto Err;
+                               *typediff = "different modifiers";
+                               return 0;
                        }
                        goto Cast;
                }
                /* It's OK if the target is more volatile or const than the 
source */
-               typediff = type_difference(&t->ctype, &s->ctype, 0, mod1);
-               if (typediff)
-                       goto Err;
+               *typediff = type_difference(&t->ctype, &s->ctype, 0, mod1);
+               if (*typediff)
+                       return 0;
                return 1;
        }
 
@@ -1379,22 +1387,60 @@
                /* XXX: need to turn into comparison with NULL */
                if (t == &bool_ctype && (sclass & TYPE_PTR))
                        goto Cast;
-               typediff = "different base types";
-               goto Err;
+               *typediff = "different base types";
+               return 0;
        }
-       typediff = "invalid types";
-
-Err:
-       warning(expr->pos, "incorrect type in %s (%s)", where, typediff);
-       info(expr->pos, "   expected %s", show_typename(target));
-       info(expr->pos, "   got %s", show_typename(source));
-       *rp = cast_to(*rp, target);
+       *typediff = "invalid types";
        return 0;
+
 Cast:
        *rp = cast_to(*rp, target);
        return 1;
 }
 
+static int compatible_assignment_types(struct expression *expr, struct symbol 
*target,
+       struct expression **rp, const char *where)
+{
+       const char *typediff;
+       struct symbol *source = degenerate(*rp);
+
+       if (!check_assignment_types(target, rp, &typediff)) {
+               warning(expr->pos, "incorrect type in %s (%s)", where, 
typediff);
+               info(expr->pos, "   expected %s", show_typename(target));
+               info(expr->pos, "   got %s", show_typename(source));
+               *rp = cast_to(*rp, target);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int compatible_transparent_union(struct symbol *target,
+       struct expression **rp)
+{
+       struct symbol *t, *member;
+       classify_type(target, &t);
+       if (t->type != SYM_UNION || !t->transparent_union)
+               return 0;
+
+       FOR_EACH_PTR(t->symbol_list, member) {
+               const char *typediff;
+               if (check_assignment_types(member, rp, &typediff))
+                       return 1;
+       } END_FOR_EACH_PTR(member);
+
+       return 0;
+}
+
+static int compatible_argument_type(struct expression *expr, struct symbol 
*target,
+       struct expression **rp, const char *where)
+{
+       if (compatible_transparent_union(target, rp))
+               return 1;
+
+       return compatible_assignment_types(expr, target, rp, where);
+}
+
 static void mark_assigned(struct expression *expr)
 {
        struct symbol *sym;
@@ -2057,7 +2103,8 @@
        }
 
        if (size == 1 && is_bool_type(type)) {
-               warning(expr->pos, "expression using sizeof bool");
+               if (Wsizeof_bool)
+                       warning(expr->pos, "expression using sizeof bool");
                size = bits_in_char;
        }
 
@@ -2161,7 +2208,7 @@
                        static char where[30];
                        examine_symbol_type(target);
                        sprintf(where, "argument %d", i);
-                       compatible_assignment_types(expr, target, p, where);
+                       compatible_argument_type(expr, target, p, where);
                }
 
                i++;
@@ -2171,17 +2218,6 @@
        return 1;
 }
 
-static struct symbol *find_struct_ident(struct symbol *ctype, struct ident 
*ident)
-{
-       struct symbol *sym;
-
-       FOR_EACH_PTR(ctype->symbol_list, sym) {
-               if (sym->ident == ident)
-                       return sym;
-       } END_FOR_EACH_PTR(sym);
-       return NULL;
-}
-
 static void convert_index(struct expression *e)
 {
        struct expression *child = e->idx_expression;
@@ -2196,9 +2232,10 @@
 static void convert_ident(struct expression *e)
 {
        struct expression *child = e->ident_expression;
-       struct symbol *sym = e->field;
+       int offset = e->offset;
+
        e->type = EXPR_POS;
-       e->init_offset = sym->offset;
+       e->init_offset = offset;
        e->init_nr = 1;
        e->init_expr = child;
 }
@@ -2250,6 +2287,7 @@
                new = alloc_expression(e->pos, EXPR_IDENTIFIER);
                new->ident_expression = e;
                new->field = new->ctype = field;
+               new->offset = field->offset;
        }
        *v = new;
        return new;
@@ -2275,7 +2313,7 @@
                        }
                        type = ctype->ctype.base_type;
                        if (ctype->bit_size >= 0 && type->bit_size >= 0) {
-                               unsigned offset = e->idx_to * type->bit_size;
+                               unsigned offset = 
array_element_offset(type->bit_size, e->idx_to);
                                if (offset >= ctype->bit_size) {
                                        err = "index out of bounds in";
                                        break;
@@ -2290,15 +2328,17 @@
                        }
                        e = e->idx_expression;
                } else if (e->type == EXPR_IDENTIFIER) {
+                       int offset = 0;
                        if (ctype->type != SYM_STRUCT && ctype->type != 
SYM_UNION) {
                                err = "field name not in struct or union";
                                break;
                        }
-                       ctype = find_struct_ident(ctype, e->expr_ident);
+                       ctype = find_identifier(e->expr_ident, 
ctype->symbol_list, &offset);
                        if (!ctype) {
                                err = "unknown field name in";
                                break;
                        }
+                       e->offset = offset;
                        e->field = e->ctype = ctype;
                        last = e;
                        if (!e->ident_expression) {
@@ -2340,7 +2380,7 @@
                                        old->ctype, e, v);
                if (!copy) {
                        n = old->idx_to + 1;
-                       if (n * old->ctype->bit_size == ctype->bit_size) {
+                       if (array_element_offset(old->ctype->bit_size, n) == 
ctype->bit_size) {
                                convert_index(old);
                                return NULL;
                        }
@@ -2358,6 +2398,7 @@
        } else if (old->type == EXPR_IDENTIFIER) {
                struct expression *copy;
                struct symbol *field;
+               int offset = 0;
 
                copy = next_designators(old->ident_expression,
                                        old->ctype, e, v);
@@ -2369,6 +2410,17 @@
                        }
                        copy = e;
                        *v = new = alloc_expression(e->pos, EXPR_IDENTIFIER);
+                       /*
+                        * We can't necessarily trust "field->offset",
+                        * because the field might be in an anonymous
+                        * union, and the field offset is then the offset
+                        * within that union.
+                        *
+                        * The "old->offset - old->field->offset"
+                        * would be the offset of such an anonymous
+                        * union.
+                        */
+                       offset = old->offset - old->field->offset;
                } else {
                        field = old->field;
                        new = alloc_expression(e->pos, EXPR_IDENTIFIER);
@@ -2378,6 +2430,7 @@
                new->expr_ident = field->ident;
                new->ident_expression = copy;
                new->ctype = field;
+               new->offset = field->offset + offset;
                convert_ident(old);
        }
        return new;
@@ -3043,10 +3096,18 @@
 {
        int declared = 0;
        struct symbol *next = sym;
+       int initialized = sym->initializer != NULL;
 
        while ((next = next->same_symbol) != NULL) {
                const char *typediff;
                evaluate_symbol(next);
+               if (initialized && next->initializer) {
+                       sparse_error(sym->pos, "symbol '%s' has multiple 
initializers (originally initialized at %s:%d)",
+                               show_ident(sym->ident),
+                               stream_name(next->pos.stream), next->pos.line);
+                       /* Only warn once */
+                       initialized = 0;
+               }
                declared++;
                typediff = type_difference(&sym->ctype, &next->ctype, 0, 0);
                if (typediff) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/expression.c 
new/sparse-20141211/expression.c
--- old/sparse-20140128/expression.c    2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/expression.c    2015-01-14 15:55:41.000000000 +0100
@@ -240,7 +240,7 @@
 
 static unsigned long long parse_num(const char *nptr, char **end)
 {
-       if (nptr[0] == '0' && tolower(nptr[1]) == 'b')
+       if (nptr[0] == '0' && tolower((unsigned char)nptr[1]) == 'b')
                return strtoull(&nptr[2], end, 2);
        return strtoull(nptr, end, 0);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/expression.h 
new/sparse-20141211/expression.h
--- old/sparse-20140128/expression.h    2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/expression.h    2015-01-14 15:55:41.000000000 +0100
@@ -149,6 +149,7 @@
                struct expression_list *expr_list;
                // EXPR_IDENTIFIER
                struct /* ident_expr */ {
+                       int offset;
                        struct ident *expr_ident;
                        struct symbol *field;
                        struct expression *ident_expression;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/ident-list.h 
new/sparse-20141211/ident-list.h
--- old/sparse-20140128/ident-list.h    2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/ident-list.h    2015-01-14 15:55:41.000000000 +0100
@@ -86,11 +86,12 @@
 IDENT(fastcall); IDENT(__fastcall__);
 IDENT(dllimport); IDENT(__dllimport__);
 IDENT(dllexport); IDENT(__dllexport__);
-IDENT(restrict); IDENT(__restrict);
+IDENT(restrict); IDENT(__restrict); IDENT(__restrict__);
 IDENT(artificial); IDENT(__artificial__);
 IDENT(leaf); IDENT(__leaf__);
 IDENT(vector_size); IDENT(__vector_size__);
 IDENT(error); IDENT(__error__);
+IDENT(static);
 
 
 /* Preprocessor idents.  Direct use of __IDENT avoids mentioning the keyword
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/lib.c new/sparse-20141211/lib.c
--- old/sparse-20140128/lib.c   2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/lib.c   2015-01-14 15:55:41.000000000 +0100
@@ -59,6 +59,7 @@
 int gcc_patchlevel = __GNUC_PATCHLEVEL__;
 
 static const char *gcc_base_dir = GCC_BASE;
+static const char *multiarch_dir = MULTIARCH_TRIPLET;
 
 struct token *skip_to(struct token *token, int op)
 {
@@ -126,25 +127,6 @@
        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 +147,32 @@
        errors++;
 }      
 
+void warning(struct position pos, const char * fmt, ...)
+{
+       va_list args;
+
+       if (Wsparse_error) {
+               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 +227,7 @@
 int Wdo_while = 0;
 int Winit_cstring = 0;
 int Wenum_mismatch = 1;
+int Wsparse_error = 0;
 int Wnon_pointer_null = 1;
 int Wold_initializer = 1;
 int Wone_bit_signed_bitfield = 1;
@@ -226,6 +235,7 @@
 int Wptr_subtraction_blows = 0;
 int Wreturn_void = 0;
 int Wshadow = 0;
+int Wsizeof_bool = 0;
 int Wtransparent_union = 0;
 int Wtypesign = 0;
 int Wundef = 0;
@@ -280,7 +290,7 @@
        const char *name = arg + 1;
        const char *value = "1";
 
-       if (!*name || isspace(*name))
+       if (!*name || isspace((unsigned char)*name))
                die("argument to `-D' is missing");
 
        for (;;) {
@@ -362,6 +372,14 @@
        return next;
 }
 
+static char **handle_multiarch_dir(char *arg, char **next)
+{
+       multiarch_dir = *++next;
+       if (!multiarch_dir)
+               die("missing argument for -multiarch-dir option");
+       return next;
+}
+
 static char **handle_switch_m(char *arg, char **next)
 {
        if (!strcmp(arg, "m64")) {
@@ -370,7 +388,8 @@
                arch_m64 = 0;
        } else if (!strcmp(arg, "msize-long")) {
                arch_msize_long = 1;
-       }
+       } else if (!strcmp(arg, "multiarch-dir"))
+               return handle_multiarch_dir(arg, next);
        return next;
 }
 
@@ -430,6 +449,7 @@
        { "designated-init", &Wdesignated_init },
        { "do-while", &Wdo_while },
        { "enum-mismatch", &Wenum_mismatch },
+       { "sparse-error", &Wsparse_error },
        { "init-cstring", &Winit_cstring },
        { "non-pointer-null", &Wnon_pointer_null },
        { "old-initializer", &Wold_initializer },
@@ -438,6 +458,7 @@
        { "ptr-subtraction-blows", &Wptr_subtraction_blows },
        { "return-void", &Wreturn_void },
        { "shadow", &Wshadow },
+       { "sizeof-bool", &Wsizeof_bool },
        { "transparent-union", &Wtransparent_union },
        { "typesign", &Wtypesign },
        { "undef", &Wundef },
@@ -460,7 +481,7 @@
 
        if (!strcmp(p, "sparse-all")) {
                for (i = 0; i < n; i++) {
-                       if (*warnings[i].flag != WARNING_FORCE_OFF)
+                       if (*warnings[i].flag != WARNING_FORCE_OFF && 
warnings[i].flag != &Wsparse_error)
                                *warnings[i].flag = WARNING_ON;
                }
        }
@@ -659,6 +680,14 @@
        return next;
 }
 
+static char **handle_switch_n(char *arg, char **next)
+{
+       if (!strcmp (arg, "nostdinc"))
+               return handle_nostdinc(arg, next);
+
+       return next;
+}
+
 static char **handle_base_dir(char *arg, char **next)
 {
        gcc_base_dir = *++next;
@@ -667,71 +696,87 @@
        return next;
 }
 
+static char **handle_switch_g(char *arg, char **next)
+{
+       if (!strcmp (arg, "gcc-base-dir"))
+               return handle_base_dir(arg, next);
+
+       return next;
+}
+
+
 static char **handle_version(char *arg, char **next)
 {
        printf("%s\n", SPARSE_VERSION);
        exit(0);
 }
 
+static char **handle_param(char *arg, char **next)
+{
+       char *value = NULL;
+
+       /* For now just skip any '--param=*' or '--param *' */
+       if (*arg == '\0') {
+               value = *++next;
+       } else if (isspace((unsigned char)*arg) || *arg == '=') {
+               value = ++arg;
+       }
+
+       if (!value)
+               die("missing argument for --param option");
+
+       return next;
+}
+
 struct switches {
        const char *name;
        char **(*fn)(char *, char **);
+       unsigned int prefix:1;
 };
 
 static char **handle_long_options(char *arg, char **next)
 {
        static struct switches cmd[] = {
+               { "param", handle_param, 1 },
                { "version", handle_version },
                { NULL, NULL }
        };
        struct switches *s = cmd;
 
        while (s->name) {
-               if (!strcmp(s->name, arg))
-                       return s->fn(arg, next);
+               int optlen = strlen(s->name);
+               if (!strncmp(s->name, arg, optlen + !s->prefix))
+                       return s->fn(arg + optlen, next);
                s++;
        }
        return next;
-
 }
 
 static char **handle_switch(char *arg, char **next)
 {
-       static struct switches cmd[] = {
-               { "nostdinc", handle_nostdinc },
-               { "gcc-base-dir", handle_base_dir},
-               { NULL, NULL }
-       };
-       struct switches *s;
-
        switch (*arg) {
+       case 'a': return handle_switch_a(arg, next);
        case 'D': return handle_switch_D(arg, next);
        case 'E': return handle_switch_E(arg, next);
+       case 'f': return handle_switch_f(arg, next);
+       case 'g': return handle_switch_g(arg, next);
+       case 'G': return handle_switch_G(arg, next);
        case 'I': return handle_switch_I(arg, next);
        case 'i': return handle_switch_i(arg, next);
        case 'M': return handle_switch_M(arg, next);
        case 'm': return handle_switch_m(arg, next);
+       case 'n': return handle_switch_n(arg, next);
        case 'o': return handle_switch_o(arg, next);
+       case 'O': return handle_switch_O(arg, next);
+       case 's': return handle_switch_s(arg, next);
        case 'U': return handle_switch_U(arg, next);
        case 'v': return handle_switch_v(arg, next);
        case 'W': return handle_switch_W(arg, next);
-       case 'O': return handle_switch_O(arg, next);
-       case 'f': return handle_switch_f(arg, next);
-       case 'G': return handle_switch_G(arg, next);
-       case 'a': return handle_switch_a(arg, next);
-       case 's': return handle_switch_s(arg, next);
        case '-': return handle_long_options(arg + 1, next);
        default:
                break;
        }
 
-       s = cmd;
-       while (s->name) {
-               if (!strcmp(s->name, arg))
-                       return s->fn(arg, next);
-               s++;
-       }
-
        /*
         * Ignore unknown command line options:
         * they're probably gcc switches
@@ -855,6 +900,12 @@
        add_pre_buffer("#weak_define __GNUC_MINOR__ %d\n", gcc_minor);
        add_pre_buffer("#weak_define __GNUC_PATCHLEVEL__ %d\n", gcc_patchlevel);
 
+       /* add the multiarch include directories, if any */
+       if (multiarch_dir && *multiarch_dir) {
+               add_pre_buffer("#add_system \"/usr/include/%s\"\n", 
multiarch_dir);
+               add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", 
multiarch_dir);
+       }
+
        /* We add compiler headers path here because we have to parse
         * the arguments to get it, falling back to default. */
        add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir);
@@ -928,6 +979,7 @@
        add_pre_buffer("#weak_define __LONG_LONG_MAX__ " 
STRINGIFY(__LONG_LONG_MAX__) "\n");
        add_pre_buffer("#weak_define __WCHAR_MAX__ " STRINGIFY(__WCHAR_MAX__) 
"\n");
        add_pre_buffer("#weak_define __SIZEOF_POINTER__ " 
STRINGIFY(__SIZEOF_POINTER__) "\n");
+       add_pre_buffer("#weak_define __CHAR_BIT__ " STRINGIFY(__CHAR_BIT__) 
"\n");
 }
 
 static struct symbol_list *sparse_tokenstream(struct token *token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/lib.h new/sparse-20141211/lib.h
--- old/sparse-20140128/lib.h   2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/lib.h   2015-01-14 15:55:41.000000000 +0100
@@ -112,6 +112,7 @@
 extern int Wdesignated_init;
 extern int Wdo_while;
 extern int Wenum_mismatch;
+extern int Wsparse_error;
 extern int Winit_cstring;
 extern int Wnon_pointer_null;
 extern int Wold_initializer;
@@ -120,6 +121,7 @@
 extern int Wptr_subtraction_blows;
 extern int Wreturn_void;
 extern int Wshadow;
+extern int Wsizeof_bool;
 extern int Wtransparent_union;
 extern int Wtypesign;
 extern int Wundef;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/parse.c new/sparse-20141211/parse.c
--- old/sparse-20140128/parse.c 2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/parse.c 2015-01-14 15:55:41.000000000 +0100
@@ -435,6 +435,7 @@
        /* Ignored for now.. */
        { "restrict",   NS_TYPEDEF, .op = &restrict_op},
        { "__restrict", NS_TYPEDEF, .op = &restrict_op},
+       { "__restrict__",       NS_TYPEDEF, .op = &restrict_op},
 
        /* Storage class */
        { "auto",       NS_TYPEDEF, .op = &auto_op },
@@ -535,6 +536,8 @@
        "__format__",
        "format_arg",
        "__format_arg__",
+       "gnu_inline",
+       "__gnu_inline__",
        "hot",
        "__hot__",
         "leaf",
@@ -545,8 +548,6 @@
        "__l1_data__",
        "l2",
        "__l2__",
-       "may_alias",
-       "__may_alias__",
        "malloc",
        "__malloc__",
        "may_alias",
@@ -1208,7 +1209,12 @@
 static struct token *attribute_transparent_union(struct token *token, struct 
symbol *attr, struct decl_state *ctx)
 {
        if (Wtransparent_union)
-               warning(token->pos, "ignoring attribute __transparent_union__");
+               warning(token->pos, "attribute __transparent_union__");
+
+       if (ctx->ctype.base_type && ctx->ctype.base_type->type == SYM_UNION)
+               ctx->ctype.base_type->transparent_union = 1;
+       else
+               warning(token->pos, "attribute __transparent_union__ applied to 
non-union type");
        return token;
 }
 
@@ -1528,12 +1534,28 @@
        return token;
 }
 
+static struct token *abstract_array_static_declarator(struct token *token, int 
*has_static)
+{
+       while (token->ident == &static_ident) {
+               if (*has_static)
+                       sparse_error(token->pos, "duplicate array static 
declarator");
+
+               *has_static = 1;
+               token = token->next;
+       }
+       return token;
+
+}
+
 static struct token *abstract_array_declarator(struct token *token, struct 
symbol *sym)
 {
        struct expression *expr = NULL;
+       int has_static = 0;
 
-       if (match_idents(token, &restrict_ident, &__restrict_ident, NULL))
-               token = token->next;
+       token = abstract_array_static_declarator(token, &has_static);
+
+       if (match_idents(token, &restrict_ident, &__restrict_ident, 
&__restrict___ident, NULL))
+               token = abstract_array_static_declarator(token->next, 
&has_static);
        token = parse_expression(token, &expr);
        sym->array_size = expr;
        return token;
@@ -2590,6 +2612,7 @@
                info(prev->definition->pos, " the previous one is here");
        } else {
                while (prev) {
+                       rebind_scope(prev, decl->scope);
                        prev->definition = decl;
                        prev = prev->same_symbol;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/scope.c new/sparse-20141211/scope.c
--- old/sparse-20140128/scope.c 2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/scope.c 2015-01-14 15:55:41.000000000 +0100
@@ -46,6 +46,20 @@
        add_symbol(&scope->symbols, sym);
 }
 
+
+void rebind_scope(struct symbol *sym, struct scope *new)
+{
+       struct scope *old = sym->scope;
+
+       if (old == new)
+               return;
+
+       if (old)
+               delete_ptr_list_entry((struct ptr_list**) &old->symbols, sym, 
1);
+
+       bind_scope(sym, new);
+}
+
 static void start_scope(struct scope **s)
 {
        struct scope *scope = __alloc_scope(0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/scope.h new/sparse-20141211/scope.h
--- old/sparse-20140128/scope.h 2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/scope.h 2015-01-14 15:55:41.000000000 +0100
@@ -55,6 +55,7 @@
 extern void end_function_scope(void);
 
 extern void bind_scope(struct symbol *, struct scope *);
+extern void rebind_scope(struct symbol *, struct scope *);
 
 extern int is_outer_scope(struct scope *);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/sort.c new/sparse-20141211/sort.c
--- old/sparse-20140128/sort.c  2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/sort.c  2015-01-14 15:55:41.000000000 +0100
@@ -99,7 +99,7 @@
        assert (nbuf >= nr);                                    \
        memcpy ((b)->list, buffer, nr * sizeof (void *));       \
        nbuf -= nr;                                             \
-       memcpy (buffer, buffer + nr, nbuf * sizeof (void *));   \
+       memmove (buffer, buffer + nr, nbuf * sizeof (void *));  \
   } while (0)
 
 #define DUMP_TO(b)                                             \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/sparse.1 new/sparse-20141211/sparse.1
--- old/sparse-20140128/sparse.1        2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/sparse.1        2015-01-14 15:55:41.000000000 +0100
@@ -24,6 +24,9 @@
 Turn on all sparse warnings, except for those explicitly disabled via
 \fB\-Wno\-something\fR.
 .TP
+.B \-Wsparse\-error
+Turn all sparse warnings into errors.
+.TP
 .B \-Waddress\-space
 Warn about code which mixes pointers to different address spaces.
 
@@ -297,6 +300,14 @@
 Sparse does not issue these warnings by default.
 .
 .TP
+.B \-Wsizeof-bool
+Warn when checking the sizeof a _Bool.
+
+C99 does not specify the sizeof a _Bool.  gcc uses 1.
+
+Sparse does not issue these warnings by default.
+.
+.TP
 .B \-Wtransparent\-union
 Warn about any declaration using the GCC extension
 \fB__attribute__((transparent_union))\fR.
@@ -327,6 +338,12 @@
 .B \-gcc-base-dir \fIdir\fR
 Look for compiler-provided system headers in \fIdir\fR/include/ and 
\fIdir\fR/include-fixed/.
 .
+.TP
+.B \-multiarch-dir \fIdir\fR
+Look for system headers in the multiarch subdirectory \fIdir\fR.
+The \fIdir\fR name would normally take the form of the target's
+normalized GNU triplet. (e.g. i386-linux-gnu).
+.
 .SH OTHER OPTIONS
 .TP
 .B \-ftabstop=WIDTH
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/sparse.c new/sparse-20141211/sparse.c
--- old/sparse-20140128/sparse.c        2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/sparse.c        2015-01-14 15:55:41.000000000 +0100
@@ -287,6 +287,9 @@
                        check_context(ep);
                }
        } END_FOR_EACH_PTR(sym);
+
+       if (Wsparse_error && die_if_error)
+               exit(1);
 }
 
 int main(int argc, char **argv)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/sparsec new/sparse-20141211/sparsec
--- old/sparse-20140128/sparsec 2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/sparsec 2015-01-14 15:55:41.000000000 +0100
@@ -34,7 +34,9 @@
 
 $DIRNAME/sparse-llvm $SPARSEOPTS > $TMPLLVM
 
-llc -o - $TMPLLVM | as -o $TMPFILE
+LLC=`"${LLVM_CONFIG:-llvm-config}" --bindir`/llc
+
+$LLC -o - $TMPLLVM | as -o $TMPFILE
 
 if [ $NEED_LINK -eq 1 ]; then
        if [ -z $OUTFILE ]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/sparsei new/sparse-20141211/sparsei
--- old/sparse-20140128/sparsei 2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/sparsei 2015-01-14 15:55:41.000000000 +0100
@@ -3,7 +3,7 @@
 set +e
 
 DIRNAME=`dirname $0`
-LLI=`llvm-config --bindir`/lli
+LLI=`"${LLVM_CONFIG:-llvm-config}" --bindir`/lli
 
 if [ $# -eq 0 ]; then
   echo "`basename $0`: no input files"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/symbol.c new/sparse-20141211/symbol.c
--- old/sparse-20140128/symbol.c        2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/symbol.c        2015-01-14 15:55:41.000000000 +0100
@@ -234,7 +234,8 @@
                return sym;
 
        if (array_size) {       
-               bit_size = base_type->bit_size * 
get_expression_value_silent(array_size);
+               bit_size = array_element_offset(base_type->bit_size,
+                                               
get_expression_value_silent(array_size));
                if (array_size->type != EXPR_VALUE) {
                        if (Wvla)
                                warning(array_size->pos, "Variable length array 
is used.");
@@ -354,6 +355,15 @@
        return nr;
 }
 
+static struct expression *get_symbol_initializer(struct symbol *sym)
+{
+       do {
+               if (sym->initializer)
+                       return sym->initializer;
+       } while ((sym = sym->same_symbol) != NULL);
+       return NULL;
+}
+
 static struct symbol * examine_node_type(struct symbol *sym)
 {
        struct symbol *base_type = examine_base_type(sym);
@@ -376,12 +386,15 @@
                sym->ctype.alignment = alignment;
 
        /* Unsized array? The size might come from the initializer.. */
-       if (bit_size < 0 && base_type->type == SYM_ARRAY && sym->initializer) {
-               struct symbol *node_type = base_type->ctype.base_type;
-               int count = count_array_initializer(node_type, 
sym->initializer);
+       if (bit_size < 0 && base_type->type == SYM_ARRAY) {
+               struct expression *initializer = get_symbol_initializer(sym);
+               if (initializer) {
+                       struct symbol *node_type = base_type->ctype.base_type;
+                       int count = count_array_initializer(node_type, 
initializer);
 
-               if (node_type && node_type->bit_size >= 0)
-                       bit_size = node_type->bit_size * count;
+                       if (node_type && node_type->bit_size >= 0)
+                               bit_size = node_type->bit_size * count;
+               }
        }
        
        sym->bit_size = bit_size;
@@ -564,11 +577,12 @@
                        sym->same_symbol = next;
                        return;
                }
-               if (sym->ctype.modifiers & next->ctype.modifiers & MOD_EXTERN) {
-                       if ((sym->ctype.modifiers ^ next->ctype.modifiers) & 
MOD_INLINE)
-                               continue;
-                       sym->same_symbol = next;
-                       return;
+               /* Extern in block level matches a TOPLEVEL non-static symbol */
+               if (sym->ctype.modifiers & MOD_EXTERN) {
+                       if ((next->ctype.modifiers & (MOD_TOPLEVEL|MOD_STATIC)) 
== MOD_TOPLEVEL) {
+                               sym->same_symbol = next;
+                               return;
+                       }
                }
 
                if (!Wshadow || warned)
@@ -888,7 +902,7 @@
                struct symbol *sym = ctype->ptr;
                unsigned long bit_size = ctype->bit_size ? *ctype->bit_size : 
-1;
                unsigned long maxalign = ctype->maxalign ? *ctype->maxalign : 0;
-               unsigned long alignment = bits_to_bytes(bit_size + bits_in_char 
- 1);
+               unsigned long alignment = bits_to_bytes(bit_size);
 
                if (alignment > maxalign)
                        alignment = maxalign;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/symbol.h new/sparse-20141211/symbol.h
--- old/sparse-20140128/symbol.h        2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/symbol.h        2015-01-14 15:55:41.000000000 +0100
@@ -174,7 +174,8 @@
                                        evaluated:1,
                                        string:1,
                                        designated_init:1,
-                                       forced_arg:1;
+                                       forced_arg:1,
+                                       transparent_union:1;
                        struct expression *array_size;
                        struct ctype ctype;
                        struct symbol_list *arguments;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/target.h new/sparse-20141211/target.h
--- old/sparse-20140128/target.h        2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/target.h        2015-01-14 15:55:41.000000000 +0100
@@ -49,7 +49,7 @@
 
 static inline int bits_to_bytes(int bits)
 {
-       return bits >= 0 ? bits / bits_in_char : -1;
+       return bits >= 0 ? (bits + bits_in_char - 1) / bits_in_char : -1;
 }
 
 static inline int bytes_to_bits(int bytes)
@@ -57,4 +57,12 @@
        return bytes * bits_in_char;
 }
 
+static inline unsigned long array_element_offset(unsigned long base_bits, int 
idx)
+{
+       int fragment = base_bits % bits_in_char;
+       if (fragment)
+               base_bits += bits_in_char - fragment;
+       return base_bits * idx;
+}
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sparse-20140128/validation/abstract-array-declarator-static.c 
new/sparse-20141211/validation/abstract-array-declarator-static.c
--- old/sparse-20140128/validation/abstract-array-declarator-static.c   
1970-01-01 01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/abstract-array-declarator-static.c   
2015-01-14 15:55:41.000000000 +0100
@@ -0,0 +1,14 @@
+
+extern void f1(int g[static 1]);
+extern void f2(int g[static restrict 1]);
+extern void f3(int g[restrict static 1]);
+extern void f4(int g[static restrict static 1]);       /* duplicate static 
error */
+extern void f5(int g[restrict static static 1]);       /* duplicate static 
error */
+
+/*
+ * check-name: abstract array declarator static
+ * check-error-start
+abstract-array-declarator-static.c:5:38: error: duplicate array static 
declarator
+abstract-array-declarator-static.c:6:38: error: duplicate array static 
declarator
+ * check-error-end
+ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/alternate-keywords.c 
new/sparse-20141211/validation/alternate-keywords.c
--- old/sparse-20140128/validation/alternate-keywords.c 1970-01-01 
01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/alternate-keywords.c 2015-01-14 
15:55:41.000000000 +0100
@@ -0,0 +1,46 @@
+
+extern float strtof(const char *__restrict__ ptr, char **__restrict__ endptr);
+extern double strtod(const char *__restrict ptr, char **__restrict endptr);
+/* restrict: -std=c99 or -std=gnu99 or -std=c11 */
+extern long double strtold(const char *restrict ptr, char **restrict endptr);
+
+extern int (*funcs[])(void);
+
+/* typeof: no -std or -std=gnu90 or -std=gnu99 or -std=gnu11 */
+extern typeof (funcs[0]) f0;
+extern __typeof (funcs[1]) f1;
+extern __typeof__(funcs[2]) f2;
+
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+static __inline__ uint16_t swap16(uint16_t val)
+{
+       return ((((uint16_t)(val) & (uint16_t)0x00ffU) << 8) |
+               (((uint16_t)(val) & (uint16_t)0xff00U) >> 8));
+}
+
+static __inline uint32_t swap32(uint32_t val)
+{
+       return ((((uint32_t)(val) & (uint32_t)0x000000ffUL) << 24) |
+               (((uint32_t)(val) & (uint32_t)0x0000ff00UL) <<  8) |
+               (((uint32_t)(val) & (uint32_t)0x00ff0000UL) >>  8) |
+               (((uint32_t)(val) & (uint32_t)0xff000000UL) >> 24));
+}
+
+/* inline: no -std or -std=gnu90 or -std=c99 or -std=c11 */
+static inline uint64_t swap64(uint64_t val)
+{
+       return ((((uint64_t)(val) & (uint64_t)0x00000000000000ffULL) << 56) |
+               (((uint64_t)(val) & (uint64_t)0x000000000000ff00ULL) << 40) |
+               (((uint64_t)(val) & (uint64_t)0x0000000000ff0000ULL) << 24) |
+               (((uint64_t)(val) & (uint64_t)0x00000000ff000000ULL) <<  8) |
+               (((uint64_t)(val) & (uint64_t)0x000000ff00000000ULL) >>  8) |
+               (((uint64_t)(val) & (uint64_t)0x0000ff0000000000ULL) >> 24) |
+               (((uint64_t)(val) & (uint64_t)0x00ff000000000000ULL) >> 40) |
+               (((uint64_t)(val) & (uint64_t)0xff00000000000000ULL) >> 56));
+}
+/*
+ * check-name: alternate keywords
+ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/anon-union.c 
new/sparse-20141211/validation/anon-union.c
--- old/sparse-20140128/validation/anon-union.c 1970-01-01 01:00:00.000000000 
+0100
+++ new/sparse-20141211/validation/anon-union.c 2015-01-14 15:55:41.000000000 
+0100
@@ -0,0 +1,11 @@
+struct s {
+        union {
+                int val;
+        };
+};
+
+static struct s foo = { .val = 5, };
+/*
+ * check-name: test anonymous union initializer
+ */
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/attr-inline.c 
new/sparse-20141211/validation/attr-inline.c
--- old/sparse-20140128/validation/attr-inline.c        1970-01-01 
01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/attr-inline.c        2015-01-14 
15:55:41.000000000 +0100
@@ -0,0 +1,21 @@
+
+static inline __attribute__((__always_inline__)) int gt(int lhs, int rhs)
+{
+       return lhs > rhs;
+}
+
+extern inline __attribute__((__gnu_inline__)) int ge(int lhs, int rhs)
+{
+       return lhs >= rhs;
+}
+
+static __attribute__((__warning__("That's junk!"))) __attribute__((__unused__))
+__attribute__((__noinline__))
+void junk(void)
+{
+       __asm__("");
+}
+
+/*
+ * check-name: inline attributes
+ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/builtin_char_bit.c 
new/sparse-20141211/validation/builtin_char_bit.c
--- old/sparse-20140128/validation/builtin_char_bit.c   1970-01-01 
01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/builtin_char_bit.c   2015-01-14 
15:55:41.000000000 +0100
@@ -0,0 +1,7 @@
+#include <limits.h>
+
+static unsigned int word_bits = sizeof(unsigned int) * CHAR_BIT;
+
+/*
+ * check-name: __CHAR_BIT__
+ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/extern-array.c 
new/sparse-20141211/validation/extern-array.c
--- old/sparse-20140128/validation/extern-array.c       1970-01-01 
01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/extern-array.c       2015-01-14 
15:55:41.000000000 +0100
@@ -0,0 +1,14 @@
+extern const char *v4l2_type_names[];
+const char *v4l2_type_names[] = {
+        "test"
+};
+extern const char *v4l2_type_names[];
+
+static void test(void)
+{
+        unsigned sz = sizeof(v4l2_type_names);
+}
+/*
+ * check-name: duplicate extern array
+ */
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sparse-20140128/validation/initializer-entry-defined-twice.c 
new/sparse-20141211/validation/initializer-entry-defined-twice.c
--- old/sparse-20140128/validation/initializer-entry-defined-twice.c    
2014-05-15 17:52:44.000000000 +0200
+++ new/sparse-20141211/validation/initializer-entry-defined-twice.c    
2015-01-14 15:55:41.000000000 +0100
@@ -41,6 +41,16 @@
        .field1 = { },
        .field2 = 0
 };
+
+/*
+ * _Bools generally take a whole byte, so ensure that we can initialize
+ * them without spewing a warning.
+ */
+static _Bool boolarray[3] = {
+       [0] = 1,
+       [1] = 1,
+};
+
 /*
  * check-name: Initializer entry defined twice
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/ioc-typecheck.c 
new/sparse-20141211/validation/ioc-typecheck.c
--- old/sparse-20140128/validation/ioc-typecheck.c      1970-01-01 
01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/ioc-typecheck.c      2015-01-14 
15:55:41.000000000 +0100
@@ -0,0 +1,17 @@
+extern unsigned int __invalid_size_argument_for_IOC;
+#define _IOC_TYPECHECK(t) \
+                ((sizeof(t) == sizeof(t[1]) && \
+                    sizeof(t) < (1 << 14)) ? \
+                   sizeof(t) : __invalid_size_argument_for_IOC)
+
+#define TEST_IOCTL (50 | (_IOC_TYPECHECK(unsigned) << 8))
+
+static unsigned iocnrs[] = {
+        [TEST_IOCTL & 0xff] = 1,
+};
+/*
+ * check-name: correct handling of _IOC_TYPECHECK
+ *
+ * check-error-start
+ * check-error-end
+ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/reserved.c 
new/sparse-20141211/validation/reserved.c
--- old/sparse-20140128/validation/reserved.c   2014-05-15 17:52:44.000000000 
+0200
+++ new/sparse-20141211/validation/reserved.c   2015-01-14 15:55:41.000000000 
+0100
@@ -30,6 +30,7 @@
 reserved.c:9:12: error: Trying to use reserved word '__const__' as identifier
 reserved.c:10:12: error: Trying to use reserved word 'restrict' as identifier
 reserved.c:11:12: error: Trying to use reserved word '__restrict' as identifier
+reserved.c:12:12: error: Trying to use reserved word '__restrict__' as 
identifier
 reserved.c:13:12: error: Trying to use reserved word 'typedef' as identifier
 reserved.c:14:12: error: Trying to use reserved word '__typeof' as identifier
 reserved.c:15:12: error: Trying to use reserved word '__typeof__' as identifier
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/restrict-array.c 
new/sparse-20141211/validation/restrict-array.c
--- old/sparse-20140128/validation/restrict-array.c     2014-05-15 
17:52:44.000000000 +0200
+++ new/sparse-20141211/validation/restrict-array.c     2015-01-14 
15:55:41.000000000 +0100
@@ -7,6 +7,31 @@
                         struct aiocb64 *__const __list[__restrict_arr],
                         int __nent, struct sigevent *__restrict __sig);
 
+#undef __restrict_arr
+#define __restrict_arr __restrict__
+
+struct gaicb;
+
+extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr],
+                         int __ent, struct sigevent *__restrict __sig);
+
+#undef __restrict_arr
+#define __restrict_arr restrict
+
+typedef struct re_pattern_buffer regex_t;
+typedef int regoff_t;
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+typedef unsigned long int size_t;
+
+extern int regexec (const regex_t *__restrict __preg,
+                   const char *__restrict __string, size_t __nmatch,
+                   regmatch_t __pmatch[__restrict_arr],
+                   int __eflags);
+
 /*
  * check-name: restrict array attribute
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/sizeof-bool.c 
new/sparse-20141211/validation/sizeof-bool.c
--- old/sparse-20140128/validation/sizeof-bool.c        2014-05-15 
17:52:44.000000000 +0200
+++ new/sparse-20141211/validation/sizeof-bool.c        2015-01-14 
15:55:41.000000000 +0100
@@ -6,6 +6,7 @@
  * check-name: sizeof(_Bool) is valid
  * check-description: sizeof(_Bool) was rejected because _Bool is not an even
  * number of bytes
+ * check-command: sparse -Wsizeof-bool $file
  * check-error-start
 sizeof-bool.c:3:16: warning: expression using sizeof bool
  * check-error-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/test-suite 
new/sparse-20141211/validation/test-suite
--- old/sparse-20140128/validation/test-suite   2014-05-15 17:52:44.000000000 
+0200
+++ new/sparse-20141211/validation/test-suite   2015-01-14 15:55:41.000000000 
+0100
@@ -7,12 +7,18 @@
 tests_list=`find . -name '*.c' | sed -e 's#^\./\(.*\)#\1#' | sort`
 prog_name=`basename $0`
 
+if [ ! -x "$default_path/sparse-llvm" ]; then
+       disabled_cmds="sparsec sparsei sparse-llvm"
+fi
+
 # counts:
 #      - tests that have not been converted to test-suite format
+#      - tests that are disabled
 #      - tests that passed
 #      - tests that failed
 #      - tests that failed but are known to fail
 unhandled_tests=0
+disabled_tests=0
 ok_tests=0
 ko_tests=0
 known_ko_tests=0
@@ -80,6 +86,7 @@
 #      - 0 if the test passed,
 #      - 1 if it failed,
 #      - 2 if it is not a "test-suite" test.
+#      - 3 if the test is disabled.
 do_test()
 {
        test_failed=0
@@ -95,8 +102,6 @@
        fi
        test_name=$last_result
 
-       echo "     TEST    $test_name ($file)"
-
        # does the test provide a specific command ?
        cmd=`eval echo $default_path/$default_cmd`
        get_value "check-command" $file
@@ -104,8 +109,28 @@
                last_result=`echo $last_result | sed -e 's/^ *//'`
                cmd=`eval echo $default_path/$last_result`
        fi
+
+       # check for disabled commands
+       set -- $cmd
+       base_cmd=`basename $1`
+       for i in $disabled_cmds; do
+               if [ "$i" = "$base_cmd" ] ; then
+                       disabled_tests=`expr $disabled_tests + 1`
+                       echo "     DISABLE $test_name ($file)"
+                       return 3
+               fi
+       done
+
+       echo "     TEST    $test_name ($file)"
+
        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
@@ -115,11 +140,6 @@
        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
@@ -168,6 +188,9 @@
        if [ "$unhandled_tests" -ne "0" ]; then
                echo "$unhandled_tests tests could not be handled by $prog_name"
        fi
+       if [ "$disabled_tests" -ne "0" ]; then
+               echo "$disabled_tests tests were disabled"
+       fi
 }
 
 ##
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sparse-20140128/validation/transparent-union.c 
new/sparse-20141211/validation/transparent-union.c
--- old/sparse-20140128/validation/transparent-union.c  1970-01-01 
01:00:00.000000000 +0100
+++ new/sparse-20141211/validation/transparent-union.c  2015-01-14 
15:55:41.000000000 +0100
@@ -0,0 +1,25 @@
+struct a {
+       int field;
+};
+struct b {
+       int field;
+};
+
+typedef union {
+       struct a *a;
+       struct b *b;
+} transparent_arg __attribute__((__transparent_union__));
+
+static void foo(transparent_arg arg)
+{
+}
+
+static void bar(void)
+{
+       struct b arg = { 0 };
+       foo((struct a *) &arg);
+}
+
+/*
+ * check-name: Transparent union attribute.
+ */

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to