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