Hello community, here is the log from the commit of package sparse for openSUSE:Factory checked in at 2019-10-10 11:53:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/sparse (Old) and /work/SRC/openSUSE:Factory/.sparse.new.2352 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sparse" Thu Oct 10 11:53:18 2019 rev:37 rq:736791 version:0.6.1rc2+20191007 Changes: -------- --- /work/SRC/openSUSE:Factory/sparse/sparse.changes 2019-07-31 14:37:22.713833075 +0200 +++ /work/SRC/openSUSE:Factory/.sparse.new.2352/sparse.changes 2019-10-10 11:53:21.451335208 +0200 @@ -1,0 +2,27 @@ +Thu Oct 10 06:31:58 UTC 2019 - [email protected] + +- Update to version 0.6.1rc2+20191007: + * expand more builtins like __builtin_ffs() + * make 'directive in argument list' clearer + * asm: warn on invalid empty constraints + * fix sign extension in casting enums + * remove useless optimization in cast_enum_list() + * add test for enum sign extension + * do not linearize invalid expression + * asm: arrays & functions in non-memory operand degenerate into pointers + * asm: fix missing expansion of asm statements + * asm: fix liveness memory operand + * asm: linearization of output memory operands is different + * asm: missing evaluation of asm statements + * asm: use parse_asm_constraint() to verify constraints + * asm: parse constraints + * asm: keep using struct asm_operand during linearization + * asm: use a specific struct for asm operands + * asm: check earlier that body & constraints are strings + * asm: add test evaluation, expansion & linearization of ASM operands + * string: use string_expression() in parse_static_assert() + * string: add helper string_expression() + * dissect: fix processing of ASM statements + * and more... + +------------------------------------------------------------------- Old: ---- sparse-0.6.1rc1+20190404.tar.xz New: ---- sparse-0.6.1rc2+20191007.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sparse.spec ++++++ --- /var/tmp/diff_new_pack.wTuRhq/_old 2019-10-10 11:53:22.299332958 +0200 +++ /var/tmp/diff_new_pack.wTuRhq/_new 2019-10-10 11:53:22.303332947 +0200 @@ -17,7 +17,7 @@ Name: sparse -Version: 0.6.1rc1+20190404 +Version: 0.6.1rc2+20191007 Release: 0 Summary: A semantic parser of source files License: MIT ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.wTuRhq/_old 2019-10-10 11:53:22.335332862 +0200 +++ /var/tmp/diff_new_pack.wTuRhq/_new 2019-10-10 11:53:22.339332852 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://git.kernel.org/pub/scm/devel/sparse/sparse.git</param> - <param name="changesrevision">2b96cd804dc7e4b5f6a0aae62c1962bd6b2caae9</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">0ccb3b4f73805d49a266a23f11d640cef8c47553</param></service></servicedata> \ No newline at end of file ++++++ sparse-0.6.1rc1+20190404.tar.xz -> sparse-0.6.1rc2+20191007.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/Makefile new/sparse-0.6.1rc2+20191007/Makefile --- old/sparse-0.6.1rc1+20190404/Makefile 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/Makefile 2019-10-07 09:46:35.000000000 +0200 @@ -1,4 +1,4 @@ -VERSION=0.6.1-rc1 +VERSION=0.6.1-rc2 ######################################################################## # The following variables can be overwritten from the command line @@ -165,7 +165,7 @@ LLVM_PROGS := sparse-llvm $(LLVM_PROGS): LD := g++ LLVM_LDFLAGS := $(shell $(LLVM_CONFIG) --ldflags) -LLVM_CFLAGS := -I$(shell $(LLVM_CONFIG) --includedir) +LLVM_CFLAGS := $(shell $(LLVM_CONFIG) --cppflags) LLVM_LIBS := $(shell $(LLVM_CONFIG) --libs) LLVM_LIBS += $(shell $(LLVM_CONFIG) --system-libs 2>/dev/null) LLVM_LIBS += $(shell $(LLVM_CONFIG) --cxxflags | grep -F -q -e '-stdlib=libc++' && echo -lc++) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/allocate.c new/sparse-0.6.1rc2+20191007/allocate.c --- old/sparse-0.6.1rc1+20190404/allocate.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/allocate.c 2019-10-07 09:46:35.000000000 +0200 @@ -141,6 +141,7 @@ ALLOCATOR(token, "tokens"); ALLOCATOR(context, "contexts"); ALLOCATOR(symbol, "symbols"); +ALLOCATOR(asm_operand, "asmops"); ALLOCATOR(expression, "expressions"); ALLOCATOR(statement, "statements"); ALLOCATOR(string, "strings"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/allocate.h new/sparse-0.6.1rc2+20191007/allocate.h --- old/sparse-0.6.1rc1+20190404/allocate.h 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/allocate.h 2019-10-07 09:46:35.000000000 +0200 @@ -82,6 +82,7 @@ DECLARE_ALLOCATOR(token); DECLARE_ALLOCATOR(context); DECLARE_ALLOCATOR(symbol); +DECLARE_ALLOCATOR(asm_operand); DECLARE_ALLOCATOR(expression); DECLARE_ALLOCATOR(statement); DECLARE_ALLOCATOR(string); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/builtin.c new/sparse-0.6.1rc2+20191007/builtin.c --- old/sparse-0.6.1rc1+20190404/builtin.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/builtin.c 2019-10-07 09:46:35.000000000 +0200 @@ -230,6 +230,44 @@ }; +#define EXPAND_FINDBIT(name) \ +static int expand_##name(struct expression *expr, int cost) \ +{ \ + struct expression *arg; \ + long long val; \ + \ + if (cost) \ + return cost; \ + \ + arg = first_expression(expr->args); \ + val = get_expression_value_silent(arg); \ + switch (arg->ctype->bit_size) { \ + case sizeof(int) * 8: \ + val = __builtin_##name(val); break; \ + case sizeof(long long) * 8: \ + val = __builtin_##name##ll(val); break; \ + default: /* impossible error */ \ + return SIDE_EFFECTS; \ + } \ + \ + expr->value = val; \ + expr->type = EXPR_VALUE; \ + expr->taint = 0; \ + return 0; \ +} \ + \ +static struct symbol_op name##_op = { \ + .evaluate = evaluate_pure_unop, \ + .expand = expand_##name, \ +} + +EXPAND_FINDBIT(clz); +EXPAND_FINDBIT(ctz); +EXPAND_FINDBIT(clrsb); +EXPAND_FINDBIT(ffs); +EXPAND_FINDBIT(parity); +EXPAND_FINDBIT(popcount); + static int evaluate_fp_unop(struct expression *expr) { struct expression *arg; @@ -334,11 +372,29 @@ { "__builtin_bswap16", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op }, { "__builtin_bswap32", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op }, { "__builtin_bswap64", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op }, + { "__builtin_clrsb", &builtin_fn_type, MOD_TOPLEVEL, &clrsb_op }, + { "__builtin_clrsbl", &builtin_fn_type, MOD_TOPLEVEL, &clrsb_op }, + { "__builtin_clrsbll", &builtin_fn_type, MOD_TOPLEVEL, &clrsb_op }, + { "__builtin_clz", &builtin_fn_type, MOD_TOPLEVEL, &clz_op }, + { "__builtin_clzl", &builtin_fn_type, MOD_TOPLEVEL, &clz_op }, + { "__builtin_clzll", &builtin_fn_type, MOD_TOPLEVEL, &clz_op }, + { "__builtin_ctz", &builtin_fn_type, MOD_TOPLEVEL, &ctz_op }, + { "__builtin_ctzl", &builtin_fn_type, MOD_TOPLEVEL, &ctz_op }, + { "__builtin_ctzll", &builtin_fn_type, MOD_TOPLEVEL, &ctz_op }, + { "__builtin_ffs", &builtin_fn_type, MOD_TOPLEVEL, &ffs_op }, + { "__builtin_ffsl", &builtin_fn_type, MOD_TOPLEVEL, &ffs_op }, + { "__builtin_ffsll", &builtin_fn_type, MOD_TOPLEVEL, &ffs_op }, { "__builtin_isfinite", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op }, { "__builtin_isinf", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op }, { "__builtin_isinf_sign", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op }, { "__builtin_isnan", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op }, { "__builtin_isnormal", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op }, + { "__builtin_parity", &builtin_fn_type, MOD_TOPLEVEL, &parity_op }, + { "__builtin_parityl", &builtin_fn_type, MOD_TOPLEVEL, &parity_op }, + { "__builtin_parityll", &builtin_fn_type, MOD_TOPLEVEL, &parity_op }, + { "__builtin_popcount", &builtin_fn_type, MOD_TOPLEVEL, &popcount_op }, + { "__builtin_popcountl", &builtin_fn_type, MOD_TOPLEVEL, &popcount_op }, + { "__builtin_popcountll", &builtin_fn_type, MOD_TOPLEVEL, &popcount_op }, { "__builtin_signbit", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op }, { "__builtin_add_overflow", &builtin_fn_type, MOD_TOPLEVEL, &overflow_op }, { "__builtin_sub_overflow", &builtin_fn_type, MOD_TOPLEVEL, &overflow_op }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/cgcc new/sparse-0.6.1rc2+20191007/cgcc --- old/sparse-0.6.1rc1+20190404/cgcc 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/cgcc 2019-10-07 09:46:35.000000000 +0200 @@ -52,7 +52,7 @@ $m32 = 1 if /^-m32$/; $m64 = 1 if /^-m64$/; - $gendeps = 1 if /^-(M|MM|MD|MMD)$/; + $gendeps = 1 if /^-(M|MM)$/; if (/^-target=(.*)$/) { $check .= &add_specs ($1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/dissect.c new/sparse-0.6.1rc2+20191007/dissect.c --- old/sparse-0.6.1rc1+20190404/dissect.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/dissect.c 2019-10-07 09:46:35.000000000 +0200 @@ -450,13 +450,9 @@ return ret; } -static void do_asm_xputs(usage_t mode, struct expression_list *xputs) +static void do_asm_xputs(usage_t mode, struct asm_operand_list *xputs) { - int nr = 0; - - DO_LIST(xputs, expr, - if (++nr % 3 == 0) - do_expression(U_W_AOF | mode, expr)); + DO_LIST(xputs, op, do_expression(U_W_AOF | mode, op->expr)); } static struct symbol *do_statement(usage_t mode, struct statement *stmt) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/evaluate.c new/sparse-0.6.1rc2+20191007/evaluate.c --- old/sparse-0.6.1rc1+20190404/evaluate.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/evaluate.c 2019-10-07 09:46:35.000000000 +0200 @@ -283,9 +283,9 @@ return; if (typea->type == SYM_ENUM && typeb->type == SYM_ENUM) { - warning(pos, "mixing different enum types"); - info(pos, " %s versus", show_typename(typea)); - info(pos, " %s", show_typename(typeb)); + warning(pos, "mixing different enum types:"); + info(pos, " %s", show_typename(typea)); + info(pos, " %s", show_typename(typeb)); } } @@ -413,16 +413,16 @@ case EXPR_COMPARE: if (!valid_subexpr_type(expr)) break; - sparse_error(expr->pos, "incompatible types for operation (%s)", show_special(expr->op)); - info(expr->pos, " left side has type %s", show_typename(expr->left->ctype)); - info(expr->pos, " right side has type %s", show_typename(expr->right->ctype)); + sparse_error(expr->pos, "incompatible types for operation (%s):", show_special(expr->op)); + info(expr->pos, " %s", show_typename(expr->left->ctype)); + info(expr->pos, " %s", show_typename(expr->right->ctype)); break; case EXPR_PREOP: case EXPR_POSTOP: if (!valid_expr_type(expr->unop)) break; - sparse_error(expr->pos, "incompatible types for operation (%s)", show_special(expr->op)); - info(expr->pos, " argument has type %s", show_typename(expr->unop->ctype)); + sparse_error(expr->pos, "incompatible type for operation (%s):", show_special(expr->op)); + info(expr->pos, " %s", show_typename(expr->unop->ctype)); break; default: break; @@ -910,8 +910,8 @@ if (Waddress) warning(expr->pos, "the address of %s will always evaluate as true", "an array"); } else if (!is_scalar_type(ctype)) { - sparse_error(expr->pos, "incorrect type in conditional (non-scalar type)"); - info(expr->pos, " got %s", show_typename(ctype)); + sparse_error(expr->pos, "non-scalar type in conditional:"); + info(expr->pos, " %s", show_typename(ctype)); return NULL; } @@ -1178,20 +1178,22 @@ expr->flags = (expr->conditional->flags & (*cond)->flags & expr->cond_false->flags & ~CEF_CONST_MASK); /* - * A conditional operator yields a particular constant - * expression type only if all of its three subexpressions are - * of that type [6.6(6), 6.6(8)]. - * As an extension, relax this restriction by allowing any - * constant expression type for the condition expression. - * - * A conditional operator never yields an address constant - * [6.6(9)]. - * However, as an extension, if the condition is any constant - * expression, and the true and false expressions are both - * address constants, mark the result as an address constant. + * In the standard, it is defined that an integer constant expression + * shall only have operands that are themselves constant [6.6(6)]. + * While this definition is very clear for expressions that need all + * their operands to be evaluated, for conditional expressions with a + * constant condition things are much less obvious. + * So, as an extension, do the same as GCC seems to do: + * Consider a conditional expression with a constant condition + * as having the same constantness as the argument corresponding + * to the truth value (including in the case of address constants + * which are defined more stricly [6.6(9)]). */ - if (expr->conditional->flags & (CEF_ACE | CEF_ADDR)) - expr->flags = (*cond)->flags & expr->cond_false->flags & ~CEF_CONST_MASK; + if (expr->conditional->flags & (CEF_ACE | CEF_ADDR)) { + int is_true = expr_truth_value(expr->conditional); + struct expression *arg = is_true ? *cond : expr->cond_false; + expr->flags = arg->flags & ~CEF_CONST_MASK; + } lclass = classify_type(ltype, <ype); rclass = classify_type(rtype, &rtype); @@ -2935,6 +2937,7 @@ * initializer, in which case we need to pass * the type value down to that initializer rather * than trying to evaluate it as an expression + * (cfr. compound literals: C99 & C11 6.5.2.5). * * A more complex case is when the initializer is * dereferenced as part of a post-fix expression. @@ -3353,9 +3356,6 @@ case EXPR_SLICE: expression_error(expr, "internal front-end error: SLICE re-evaluated"); return NULL; - case EXPR_ASM_OPERAND: - expression_error(expr, "internal front-end error: ASM_OPERAND evaluated"); - return NULL; } return NULL; } @@ -3495,48 +3495,131 @@ evaluate_statement(stmt->iterator_post_statement); } -static void verify_output_constraint(struct expression *expr, const char *constraint) + +static void parse_asm_constraint(struct asm_operand *op) { - switch (*constraint) { - case '=': /* Assignment */ - case '+': /* Update */ + struct expression *constraint = op->constraint; + const char *str = constraint->string->data; + int c; + + switch (str[0]) { + case '\0': + sparse_error(constraint->pos, "invalid ASM constraint (\"\")"); + break; + case '+': + op->is_modify = true; + /* fall-through */ + case '=': + op->is_assign = true; + str++; break; - default: - expression_error(expr, "output constraint is not an assignment constraint (\"%s\")", constraint); } + + while ((c = *str++)) { + switch (c) { + case '=': + case '+': + sparse_error(constraint->pos, "invalid ASM constraint '%c'", c); + break; + + case '&': + op->is_earlyclobber = true; + break; + case '%': + op->is_commutative = true; + break; + case 'r': + op->is_register = true; + break; + + case 'm': + case 'o': + case 'V': + case 'Q': + op->is_memory = true; + break; + + case '<': + case '>': + // FIXME: ignored for now + break; + + case ',': + // FIXME: multiple alternative constraints + break; + + case '0' ... '9': + // FIXME: numeric matching constraint? + break; + case '[': + // FIXME: symbolic matching constraint + return; + + default: + // FIXME: arch-specific (and multi-letter) constraints + break; + } + } + + // FIXME: how to deal with multi-constraint? + if (op->is_register) + op->is_memory = 0; +} + +static void verify_output_constraint(struct asm_operand *op) +{ + struct expression *expr = op->constraint; + const char *constraint = expr->string->data; + + if (!op->is_assign) + expression_error(expr, "output constraint is not an assignment constraint (\"%s\")", constraint); } -static void verify_input_constraint(struct expression *expr, const char *constraint) +static void verify_input_constraint(struct asm_operand *op) { - switch (*constraint) { - case '=': /* Assignment */ - case '+': /* Update */ + struct expression *expr = op->constraint; + const char *constraint = expr->string->data; + + if (op->is_assign) expression_error(expr, "input constraint with assignment (\"%s\")", constraint); +} + +static void evaluate_asm_memop(struct asm_operand *op) +{ + if (op->is_memory) { + struct expression *expr = op->expr; + struct expression *addr; + + // implicit addressof + addr = alloc_expression(expr->pos, EXPR_PREOP); + addr->op = '&'; + addr->unop = expr; + + evaluate_addressof(addr); + op->expr = addr; + } else { + evaluate_expression(op->expr); + degenerate(op->expr); } } static void evaluate_asm_statement(struct statement *stmt) { struct expression *expr; - struct expression *op; + struct asm_operand *op; struct symbol *sym; - expr = stmt->asm_string; - if (!expr || expr->type != EXPR_STRING) { - sparse_error(stmt->pos, "need constant string for inline asm"); + if (!stmt->asm_string) return; - } FOR_EACH_PTR(stmt->asm_outputs, op) { /* Identifier */ /* Constraint */ - expr = op->constraint; - if (!expr || expr->type != EXPR_STRING) { - sparse_error(expr ? expr->pos : stmt->pos, "asm output constraint is not a string"); - op->constraint = NULL; - } else - verify_output_constraint(expr, expr->string->data); + if (op->constraint) { + parse_asm_constraint(op); + verify_output_constraint(op); + } /* Expression */ expr = op->expr; @@ -3545,22 +3628,22 @@ if (!lvalue_expression(expr)) warning(expr->pos, "asm output is not an lvalue"); evaluate_assign_to(expr, expr->ctype); + evaluate_asm_memop(op); } END_FOR_EACH_PTR(op); FOR_EACH_PTR(stmt->asm_inputs, op) { /* Identifier */ /* Constraint */ - expr = op->constraint; - if (!expr || expr->type != EXPR_STRING) { - sparse_error(expr ? expr->pos : stmt->pos, "asm input constraint is not a string"); - op->constraint = NULL; - } else - verify_input_constraint(expr, expr->string->data); + if (op->constraint) { + parse_asm_constraint(op); + verify_input_constraint(op); + } /* Expression */ if (!evaluate_expression(op->expr)) return; + evaluate_asm_memop(op); } END_FOR_EACH_PTR(op); FOR_EACH_PTR(stmt->asm_clobbers, expr) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/expand.c new/sparse-0.6.1rc2+20191007/expand.c --- old/sparse-0.6.1rc1+20190404/expand.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/expand.c 2019-10-07 09:46:35.000000000 +0200 @@ -66,6 +66,14 @@ expr->taint = 0; return 0; } + + // expand compound literals (C99 & C11 6.5.2.5) + // FIXME: is this the correct way to identify them? + // All compound literals are anonymous but is + // the reverse true? + if (sym->initializer && !expr->symbol_name) + return expand_expression(sym->initializer); + /* The cost of a symbol expression is lower for on-stack symbols */ return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1; } @@ -1095,9 +1103,6 @@ case EXPR_OFFSETOF: expression_error(expr, "internal front-end error: sizeof in expansion?"); return UNSAFE; - case EXPR_ASM_OPERAND: - expression_error(expr, "internal front-end error: ASM_OPERAND in expansion?"); - return UNSAFE; } return SIDE_EFFECTS; } @@ -1167,6 +1172,22 @@ return SIDE_EFFECTS; } +static int expand_asm_statement(struct statement *stmt) +{ + struct asm_operand *op; + int cost = 0; + + FOR_EACH_PTR(stmt->asm_outputs, op) { + cost += expand_expression(op->expr); + } END_FOR_EACH_PTR(op); + + FOR_EACH_PTR(stmt->asm_inputs, op) { + cost += expand_expression(op->expr); + } END_FOR_EACH_PTR(op); + + return cost; +} + /* * Expanding a compound statement is really just * about adding up the costs of each individual @@ -1257,7 +1278,7 @@ case STMT_NONE: break; case STMT_ASM: - /* FIXME! Do the asm parameter evaluation! */ + expand_asm_statement(stmt); break; case STMT_CONTEXT: expand_expression(stmt->expression); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/expression.c new/sparse-0.6.1rc2+20191007/expression.c --- old/sparse-0.6.1rc1+20190404/expression.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/expression.c 2019-10-07 09:46:35.000000000 +0200 @@ -83,6 +83,17 @@ return expect(token, ')', where); } +struct token *string_expression(struct token *token, struct expression **expr, const char *where) +{ + struct token *next = primary_expression(token, expr); + + if (!*expr || (*expr)->type != EXPR_STRING) { + sparse_error(token->pos, "string literal expected for %s", where); + *expr = NULL; + } + return next; +} + /* * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token * conversion diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/expression.h new/sparse-0.6.1rc2+20191007/expression.h --- old/sparse-0.6.1rc1+20190404/expression.h 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/expression.h 2019-10-07 09:46:35.000000000 +0200 @@ -64,7 +64,6 @@ EXPR_FVALUE, EXPR_SLICE, EXPR_OFFSETOF, - EXPR_ASM_OPERAND, }; @@ -136,6 +135,18 @@ Taint_comma = 1, }; /* for expr->taint */ +struct asm_operand { + struct ident *name; + struct expression *constraint; + struct expression *expr; + unsigned int is_assign:1; + unsigned int is_modify:1; + unsigned int is_earlyclobber:1; + unsigned int is_commutative:1; + unsigned int is_register:1; + unsigned int is_memory:1; +}; + struct expression { enum expression_type type:8; unsigned flags:8; @@ -235,12 +246,6 @@ struct expression *index; }; }; - // EXPR_ASM_OPERAND - struct { - struct ident *name; - struct expression *constraint; - struct expression *expr; - }; }; }; @@ -270,6 +275,7 @@ struct token *conditional_expression(struct token *token, struct expression **tree); struct token *primary_expression(struct token *token, struct expression **tree); struct token *parens_expression(struct token *token, struct expression **expr, const char *where); +struct token *string_expression(struct token *token, struct expression **expr, const char *where); struct token *assignment_expression(struct token *token, struct expression **tree); extern int expand_symbol(struct symbol *); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/inline.c new/sparse-0.6.1rc2+20191007/inline.c --- old/sparse-0.6.1rc1+20190404/inline.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/inline.c 2019-10-07 09:46:35.000000000 +0200 @@ -274,26 +274,24 @@ } break; } - case EXPR_ASM_OPERAND: { - expr = dup_expression(expr); - expr->constraint = copy_expression(expr->constraint); - expr->expr = copy_expression(expr->expr); - break; - } default: warning(expr->pos, "trying to copy expression type %d", expr->type); } return expr; } -static struct expression_list *copy_asm_constraints(struct expression_list *in) +static struct asm_operand_list *copy_asm_operands(struct asm_operand_list *in) { - struct expression_list *out = NULL; - struct expression *expr; + struct asm_operand_list *out = NULL; + struct asm_operand *old; - FOR_EACH_PTR(in, expr) { - add_expression(&out, copy_expression(expr)); - } END_FOR_EACH_PTR(expr); + FOR_EACH_PTR(in, old) { + struct asm_operand *new = __alloc_asm_operand(0); + new->name = old->name; + new->constraint = copy_expression(old->constraint); + new->expr = copy_expression(old->expr); + add_ptr_list(&out, new); + } END_FOR_EACH_PTR(old); return out; } @@ -445,8 +443,8 @@ } case STMT_ASM: { stmt = dup_statement(stmt); - stmt->asm_inputs = copy_asm_constraints(stmt->asm_inputs); - stmt->asm_outputs = copy_asm_constraints(stmt->asm_outputs); + stmt->asm_inputs = copy_asm_operands(stmt->asm_inputs); + stmt->asm_outputs = copy_asm_operands(stmt->asm_outputs); /* no need to dup "clobbers", since they are all constant strings */ break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/lib.c new/sparse-0.6.1rc2+20191007/lib.c --- old/sparse-0.6.1rc1+20190404/lib.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/lib.c 2019-10-07 09:46:35.000000000 +0200 @@ -322,8 +322,8 @@ STANDARD_GNU89, STANDARD_GNU99, } standard = STANDARD_GNU89; +static int arch_msize_long = 0; int arch_m64 = ARCH_M64_DEFAULT; -int arch_msize_long = 0; int arch_big_endian = ARCH_BIG_ENDIAN; int arch_mach = MACH_NATIVE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/lib.h new/sparse-0.6.1rc2+20191007/lib.h --- old/sparse-0.6.1rc1+20190404/lib.h 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/lib.h 2019-10-07 09:46:35.000000000 +0200 @@ -67,6 +67,7 @@ struct token; struct symbol; struct statement; +struct asm_operand; struct expression; struct basic_block; struct entrypoint; @@ -76,6 +77,7 @@ DECLARE_PTR_LIST(symbol_list, struct symbol); DECLARE_PTR_LIST(statement_list, struct statement); +DECLARE_PTR_LIST(asm_operand_list, struct asm_operand); DECLARE_PTR_LIST(expression_list, struct expression); DECLARE_PTR_LIST(basic_block_list, struct basic_block); DECLARE_PTR_LIST(instruction_list, struct instruction); @@ -200,7 +202,6 @@ extern int funsigned_char; extern int arch_m64; -extern int arch_msize_long; extern int arch_big_endian; extern int arch_mach; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/linearize.c new/sparse-0.6.1rc2+20191007/linearize.c --- old/sparse-0.6.1rc1+20190404/linearize.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/linearize.c 2019-10-07 09:46:35.000000000 +0200 @@ -1764,7 +1764,7 @@ { pseudo_t cond; - if (!expr || !bb_reachable(ep->active)) + if (!expr || !valid_type(expr->ctype) || !bb_reachable(ep->active)) return VOID; switch (expr->type) { @@ -1864,7 +1864,7 @@ static pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr) { - if (!expr) + if (!expr || !valid_type(expr->ctype)) return VOID; current_pos = expr->pos; @@ -2075,41 +2075,45 @@ ALLOCATOR(asm_rules, "asm rules"); ALLOCATOR(asm_constraint, "asm constraints"); -static void add_asm_input(struct entrypoint *ep, struct instruction *insn, struct expression *expr, - const char *constraint, const struct ident *ident) +static void add_asm_input(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op) { - pseudo_t pseudo = linearize_expression(ep, expr); + pseudo_t pseudo = linearize_expression(ep, op->expr); struct asm_constraint *rule = __alloc_asm_constraint(0); - rule->ident = ident; - rule->constraint = constraint; + rule->ident = op->name; + rule->constraint = op->constraint ? op->constraint->string->data : ""; use_pseudo(insn, pseudo, &rule->pseudo); add_ptr_list(&insn->asm_rules->inputs, rule); } -static void add_asm_output(struct entrypoint *ep, struct instruction *insn, struct expression *expr, - const char *constraint, const struct ident *ident) +static void add_asm_output(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op) { struct access_data ad = { NULL, }; - pseudo_t pseudo = alloc_pseudo(insn); + pseudo_t pseudo; struct asm_constraint *rule; - if (!expr || !linearize_address_gen(ep, expr, &ad)) - return; - linearize_store_gen(ep, pseudo, &ad); + if (op->is_memory) { + pseudo = linearize_expression(ep, op->expr); + } else { + if (!linearize_address_gen(ep, op->expr, &ad)) + return; + pseudo = alloc_pseudo(insn); + linearize_store_gen(ep, pseudo, &ad); + } rule = __alloc_asm_constraint(0); - rule->ident = ident; - rule->constraint = constraint; + rule->is_memory = op->is_memory; + rule->ident = op->name; + rule->constraint = op->constraint ? op->constraint->string->data : ""; use_pseudo(insn, pseudo, &rule->pseudo); add_ptr_list(&insn->asm_rules->outputs, rule); } static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement *stmt) { - struct expression *expr; struct instruction *insn; + struct expression *expr; struct asm_rules *rules; - const char *constraint; + struct asm_operand *op; insn = alloc_instruction(OP_ASM, 0); expr = stmt->asm_string; @@ -2123,18 +2127,16 @@ insn->asm_rules = rules; /* Gather the inputs.. */ - FOR_EACH_PTR(stmt->asm_inputs, expr) { - constraint = expr->constraint ? expr->constraint->string->data : ""; - add_asm_input(ep, insn, expr->expr, constraint, expr->name); - } END_FOR_EACH_PTR(expr); + FOR_EACH_PTR(stmt->asm_inputs, op) { + add_asm_input(ep, insn, op); + } END_FOR_EACH_PTR(op); add_one_insn(ep, insn); /* Assign the outputs */ - FOR_EACH_PTR(stmt->asm_outputs, expr) { - constraint = expr->constraint ? expr->constraint->string->data : ""; - add_asm_output(ep, insn, expr->expr, constraint, expr->name); - } END_FOR_EACH_PTR(expr); + FOR_EACH_PTR(stmt->asm_outputs, op) { + add_asm_output(ep, insn, op); + } END_FOR_EACH_PTR(op); return VOID; } @@ -2417,6 +2419,10 @@ bb_true = alloc_basic_block(ep, stmt->pos); bb_false = endif = alloc_basic_block(ep, stmt->pos); + // If the condition is invalid, the following + // statement(s) are not evaluated. + if (!cond || !valid_type(cond->ctype)) + return VOID; linearize_cond_branch(ep, cond, bb_true, bb_false); set_activeblock(ep, bb_true); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/linearize.h new/sparse-0.6.1rc2+20191007/linearize.h --- old/sparse-0.6.1rc1+20190404/linearize.h 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/linearize.h 2019-10-07 09:46:35.000000000 +0200 @@ -68,6 +68,7 @@ pseudo_t pseudo; const char *constraint; const struct ident *ident; + unsigned int is_memory:1; }; DECLARE_ALLOCATOR(asm_constraint); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/liveness.c new/sparse-0.6.1rc2+20191007/liveness.c --- old/sparse-0.6.1rc1+20190404/liveness.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/liveness.c 2019-10-07 09:46:35.000000000 +0200 @@ -39,7 +39,10 @@ } END_FOR_EACH_PTR(entry); FOR_EACH_PTR(insn->asm_rules->outputs, entry) { - def(bb, entry->pseudo); + if (entry->is_memory) + use(bb, entry->pseudo); + else + def(bb, entry->pseudo); } END_FOR_EACH_PTR(entry); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/parse.c new/sparse-0.6.1rc2+20191007/parse.c --- old/sparse-0.6.1rc1+20190404/parse.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/parse.c 2019-10-07 09:46:35.000000000 +0200 @@ -897,10 +897,8 @@ expr->ctype = &int_ctype; continue; } - expr->ctype = base_type; - if (ctype->bit_size == base_type->bit_size) - continue; cast_value(expr, base_type, expr, ctype); + expr->ctype = base_type; } END_FOR_EACH_PTR(sym); } @@ -2051,22 +2049,23 @@ } static struct token *parse_asm_operands(struct token *token, struct statement *stmt, - struct expression_list **inout) + struct asm_operand_list **inout) { /* Allow empty operands */ if (match_op(token->next, ':') || match_op(token->next, ')')) return token->next; do { - struct expression *op = alloc_expression(token->pos, EXPR_ASM_OPERAND); + struct asm_operand *op = __alloc_asm_operand(0); if (match_op(token->next, '[') && token_type(token->next->next) == TOKEN_IDENT && match_op(token->next->next->next, ']')) { op->name = token->next->next->ident; token = token->next->next->next; } - token = primary_expression(token->next, &op->constraint); + token = token->next; + token = string_expression(token, &op->constraint, "asm constraint"); token = parens_expression(token, &op->expr, "in asm parameter"); - add_expression(inout, op); + add_ptr_list(inout, op); } while (match_op(token, ',')); return token; } @@ -2115,7 +2114,7 @@ token = token->next; } token = expect(token, '(', "after asm"); - token = parse_expression(token, &stmt->asm_string); + token = string_expression(token, &stmt->asm_string, "inline asm"); if (match_op(token, ':')) token = parse_asm_operands(token, stmt, &stmt->asm_outputs); if (match_op(token, ':')) @@ -2132,7 +2131,7 @@ { struct expression *expr; token = expect(token, '(', "after asm"); - token = parse_expression(token->next, &expr); + token = string_expression(token, &expr, "inline asm"); token = expect(token, ')', "after asm"); return token; } @@ -2146,14 +2145,9 @@ if (!cond) sparse_error(token->pos, "Expected constant expression"); token = expect(token, ',', "after conditional expression in _Static_assert"); - token = parse_expression(token, &message); - if (!message || message->type != EXPR_STRING) { - struct position pos; - - pos = message ? message->pos : token->pos; - sparse_error(pos, "bad or missing string literal"); + token = string_expression(token, &message, "_Static_assert()"); + if (!message) cond = NULL; - } token = expect(token, ')', "after diagnostic message in _Static_assert"); token = expect(token, ';', "after _Static_assert()"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/parse.h new/sparse-0.6.1rc2+20191007/parse.h --- old/sparse-0.6.1rc1+20190404/parse.h 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/parse.h 2019-10-07 09:46:35.000000000 +0200 @@ -106,8 +106,8 @@ }; struct /* asm */ { struct expression *asm_string; - struct expression_list *asm_outputs; - struct expression_list *asm_inputs; + struct asm_operand_list *asm_outputs; + struct asm_operand_list *asm_inputs; struct expression_list *asm_clobbers; struct symbol_list *asm_labels; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/pre-process.c new/sparse-0.6.1rc2+20191007/pre-process.c --- old/sparse-0.6.1rc1+20190404/pre-process.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/pre-process.c 2019-10-07 09:46:35.000000000 +0200 @@ -272,7 +272,7 @@ if (next->pos.newline && match_op(next, '#')) { if (!next->pos.noexpand) { sparse_error(next->pos, - "directive in argument list"); + "directive in macro's argument list"); preprocessor_line(stream, p); __free_token(next); /* Free the '#' token */ continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/show-parse.c new/sparse-0.6.1rc2+20191007/show-parse.c --- old/sparse-0.6.1rc1+20190404/show-parse.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/show-parse.c 2019-10-07 09:46:35.000000000 +0200 @@ -1185,9 +1185,6 @@ case EXPR_TYPE: warning(expr->pos, "unable to show type expression"); return 0; - case EXPR_ASM_OPERAND: - warning(expr->pos, "unable to show asm operand expression"); - return 0; } return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/asm-bad0.c new/sparse-0.6.1rc2+20191007/validation/asm-bad0.c --- old/sparse-0.6.1rc1+20190404/validation/asm-bad0.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/asm-bad0.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,41 @@ +extern char string[]; +extern int *var; + +static void templ(void) +{ + asm(string); +} + +static void ocons(void) +{ + asm("template" : [out] string (var) : [in] "r" (0)); +} + +static void icons(void) +{ + asm("template" : [out] "=r" (var): [in] string (0)); +} + +static void oexpr(oid) +{ + asm("template" : [out] "=" (var[) : [in] "r" (0)); +} + +static void iexpr(void) +{ + asm("template" : [out] "=r" (var) : [in] "r" (var[)); +} + +/* + * check-name: asm-bad0 + * + * check-error-start +asm-bad0.c:6:13: error: string literal expected for inline asm +asm-bad0.c:11:32: error: string literal expected for asm constraint +asm-bad0.c:16:49: error: string literal expected for asm constraint +asm-bad0.c:21:41: error: Expected ] at end of array dereference +asm-bad0.c:21:41: error: got ) +asm-bad0.c:26:59: error: Expected ] at end of array dereference +asm-bad0.c:26:59: error: got ) + * check-error-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/bad-type-twice0.c new/sparse-0.6.1rc2+20191007/validation/bad-type-twice0.c --- old/sparse-0.6.1rc1+20190404/validation/bad-type-twice0.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/bad-type-twice0.c 2019-10-07 09:46:35.000000000 +0200 @@ -7,7 +7,7 @@ * check-name: bad-type-twice0 * * check-error-start -bad-type-twice0.c:3:16: error: incorrect type in conditional (non-scalar type) -bad-type-twice0.c:3:16: got incomplete type a +bad-type-twice0.c:3:16: error: non-scalar type in conditional: +bad-type-twice0.c:3:16: incomplete type a * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/bad-type-twice1.c new/sparse-0.6.1rc2+20191007/validation/bad-type-twice1.c --- old/sparse-0.6.1rc1+20190404/validation/bad-type-twice1.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/bad-type-twice1.c 2019-10-07 09:46:35.000000000 +0200 @@ -9,8 +9,8 @@ * check-name: bad-type-twice1 * * check-error-start -bad-type-twice1.c:3:17: error: incompatible types for operation (>=) -bad-type-twice1.c:3:17: left side has type unsigned long val -bad-type-twice1.c:3:17: right side has type void *ref +bad-type-twice1.c:3:17: error: incompatible types for operation (>=): +bad-type-twice1.c:3:17: unsigned long val +bad-type-twice1.c:3:17: void *ref * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/compare-null-to-int.c new/sparse-0.6.1rc2+20191007/validation/compare-null-to-int.c --- old/sparse-0.6.1rc1+20190404/validation/compare-null-to-int.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/compare-null-to-int.c 2019-10-07 09:46:35.000000000 +0200 @@ -4,8 +4,8 @@ * check-description: Sparse used to allow this. * * check-error-start -compare-null-to-int.c:1:44: error: incompatible types for operation (==) -compare-null-to-int.c:1:44: left side has type void * -compare-null-to-int.c:1:44: right side has type int +compare-null-to-int.c:1:44: error: incompatible types for operation (==): +compare-null-to-int.c:1:44: void * +compare-null-to-int.c:1:44: int * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/cond_expr.c new/sparse-0.6.1rc2+20191007/validation/cond_expr.c --- old/sparse-0.6.1rc1+20190404/validation/cond_expr.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/cond_expr.c 2019-10-07 09:46:35.000000000 +0200 @@ -13,7 +13,7 @@ * check-name: Two-argument conditional expression types * * check-error-start -cond_expr.c:10:16: error: incompatible types for operation (~) -cond_expr.c:10:16: argument has type double +cond_expr.c:10:16: error: incompatible type for operation (~): +cond_expr.c:10:16: double * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/conditional-type.c new/sparse-0.6.1rc2+20191007/validation/conditional-type.c --- old/sparse-0.6.1rc1+20190404/validation/conditional-type.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/conditional-type.c 2019-10-07 09:46:35.000000000 +0200 @@ -79,21 +79,21 @@ * check-name: conditional-type * * check-error-start -conditional-type.c:18:18: error: incorrect type in conditional (non-scalar type) -conditional-type.c:18:18: got void -conditional-type.c:19:13: error: incorrect type in conditional (non-scalar type) -conditional-type.c:19:13: got struct state s -conditional-type.c:24:18: error: incorrect type in conditional (non-scalar type) -conditional-type.c:24:18: got void -conditional-type.c:29:21: error: incorrect type in conditional (non-scalar type) -conditional-type.c:29:21: got void -conditional-type.c:30:16: error: incorrect type in conditional (non-scalar type) -conditional-type.c:30:16: got struct state s -conditional-type.c:34:21: error: incorrect type in conditional (non-scalar type) -conditional-type.c:34:21: got void -conditional-type.c:36:20: error: incorrect type in conditional (non-scalar type) -conditional-type.c:36:20: got void -conditional-type.c:40:21: error: incorrect type in conditional (non-scalar type) -conditional-type.c:40:21: got void +conditional-type.c:18:18: error: non-scalar type in conditional: +conditional-type.c:18:18: void +conditional-type.c:19:13: error: non-scalar type in conditional: +conditional-type.c:19:13: struct state s +conditional-type.c:24:18: error: non-scalar type in conditional: +conditional-type.c:24:18: void +conditional-type.c:29:21: error: non-scalar type in conditional: +conditional-type.c:29:21: void +conditional-type.c:30:16: error: non-scalar type in conditional: +conditional-type.c:30:16: struct state s +conditional-type.c:34:21: error: non-scalar type in conditional: +conditional-type.c:34:21: void +conditional-type.c:36:20: error: non-scalar type in conditional: +conditional-type.c:36:20: void +conditional-type.c:40:21: error: non-scalar type in conditional: +conditional-type.c:40:21: void * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/constexpr-constcond.c new/sparse-0.6.1rc2+20191007/validation/constexpr-constcond.c --- old/sparse-0.6.1rc1+20190404/validation/constexpr-constcond.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/constexpr-constcond.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,10 @@ +extern int var; + +static int a[] = { + [0 ? var : 1] = 0, + [1 ? 2 : var] = 0, +}; + +/* + * check-name: constexprness in constant conditionals + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/enum-mismatch.c new/sparse-0.6.1rc2+20191007/validation/enum-mismatch.c --- old/sparse-0.6.1rc1+20190404/validation/enum-mismatch.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/enum-mismatch.c 2019-10-07 09:46:35.000000000 +0200 @@ -12,8 +12,8 @@ * check-command: sparse -Wenum-mismatch $file * * check-error-start -enum-mismatch.c:7:16: warning: mixing different enum types -enum-mismatch.c:7:16: unsigned int enum ea versus -enum-mismatch.c:7:16: unsigned int enum eb +enum-mismatch.c:7:16: warning: mixing different enum types: +enum-mismatch.c:7:16: unsigned int enum ea +enum-mismatch.c:7:16: unsigned int enum eb * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/enum-sign-extend.c new/sparse-0.6.1rc2+20191007/validation/enum-sign-extend.c --- old/sparse-0.6.1rc1+20190404/validation/enum-sign-extend.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/enum-sign-extend.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,12 @@ +enum num { + a = 0x80000000, + b = -1, +}; + +_Static_assert([typeof(b)] == [long], "type"); +_Static_assert(b == -1L, "value"); + +/* + * check-name: enum-sign-extend + * check-command: sparse -m64 $file + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/eval/asm-degen.c new/sparse-0.6.1rc2+20191007/validation/eval/asm-degen.c --- old/sparse-0.6.1rc1+20190404/validation/eval/asm-degen.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/eval/asm-degen.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,36 @@ +#ifdef __CHECKER__ +#define __percpu __attribute__((noderef)) +#else +#define __percpu +#endif + +static __percpu int var; +static __percpu int arr[4]; + +static void foo(void) +{ + asm("" :: "r" (var)); +} + +static void bar(void) +{ + asm("" :: "r" (arr)); +} + +static void baz(void) +{ + asm("" :: "m" (var)); +} + +static void qux(void) +{ + asm("" :: "m" (arr)); +} + +/* + * check-name: asm-degen + * + * check-error-start +eval/asm-degen.c:12:24: warning: dereference of noderef expression + * check-error-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/eval/asm-memop.c new/sparse-0.6.1rc2+20191007/validation/eval/asm-memop.c --- old/sparse-0.6.1rc1+20190404/validation/eval/asm-memop.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/eval/asm-memop.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,47 @@ +extern int g; + +void fo0(int *p) { asm volatile ("op %0" :: "p" (&g)); } +void fo1(int *p) { asm volatile ("op %0" :: "m" (g)); } + +void fo2(int *p) { asm volatile ("op %0" :: "p" (p)); } +void fo3(int *p) { asm volatile ("op %0" :: "m" (*p)); } + +/* + * check-name: eval-asm-memop + * check-command: test-linearize -Wno-decl $file + * + * check-output-start +fo0: +.L0: + <entry-point> + asm "op %0" + in: "p" (g) + ret + + +fo1: +.L2: + <entry-point> + asm "op %0" + in: "m" (g) + ret + + +fo2: +.L4: + <entry-point> + asm "op %0" + in: "p" (%arg1) + ret + + +fo3: +.L6: + <entry-point> + asm "op %0" + in: "m" (%arg1) + ret + + + * check-output-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/eval-bad-assign1.c new/sparse-0.6.1rc2+20191007/validation/eval-bad-assign1.c --- old/sparse-0.6.1rc1+20190404/validation/eval-bad-assign1.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/eval-bad-assign1.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,14 @@ +static void kos(int *r, int a) +{ + r = ({ __builtin_types_compatible_p(int, int); }); +} + +/* + * check-name: eval-bad-assign1 + * + * check-error-start +eval-bad-assign1.c:3:11: warning: incorrect type in assignment (different base types) +eval-bad-assign1.c:3:11: expected int *r +eval-bad-assign1.c:3:11: got int + * check-error-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/eval-bad-assign2.c new/sparse-0.6.1rc2+20191007/validation/eval-bad-assign2.c --- old/sparse-0.6.1rc1+20190404/validation/eval-bad-assign2.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/eval-bad-assign2.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,22 @@ +struct s { + char c[1]; +}; + +struct s fun(void); + + +static void foo(void) +{ + char c[1]; + c = fun().c; +} + +/* + * check-name: eval-bad-assign2 + * + * check-error-start +eval-bad-assign2.c:11:11: warning: incorrect type in assignment (invalid types) +eval-bad-assign2.c:11:11: expected char c[1] +eval-bad-assign2.c:11:11: got char * + * check-error-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/expand/asm0.c new/sparse-0.6.1rc2+20191007/validation/expand/asm0.c --- old/sparse-0.6.1rc1+20190404/validation/expand/asm0.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/expand/asm0.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,23 @@ +static void foo(void) +{ + asm("" :: "i" (42 & 3)); + asm("" :: "i" (__builtin_constant_p(0))); +} + +/* + * check-name: expand-asm0 + * check-command: test-linearize $file + * + * check-output-start +foo: +.L0: + <entry-point> + asm "" + in: "i" ($2) + asm "" + in: "i" ($1) + ret + + + * check-output-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/expand/compound-literal.c new/sparse-0.6.1rc2+20191007/validation/expand/compound-literal.c --- old/sparse-0.6.1rc1+20190404/validation/expand/compound-literal.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/expand/compound-literal.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,26 @@ +#define SAME_TYPE(A, B) \ + __builtin_types_compatible_p(A, B) + +struct s { + int i; +}; + +static void foo(struct s *p) +{ + *p = (struct s) { .i = SAME_TYPE(int, int), }; +} + +/* + * check-name: compound-literal + * check-command: test-linearize $file + * + * check-output-start +foo: +.L0: + <entry-point> + store.32 $1 -> 0[%arg1] + ret + + + * check-output-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/ioc-typecheck.c new/sparse-0.6.1rc2+20191007/validation/ioc-typecheck.c --- old/sparse-0.6.1rc1+20190404/validation/ioc-typecheck.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/ioc-typecheck.c 2019-10-07 09:46:35.000000000 +0200 @@ -4,8 +4,4 @@ }; /* * check-name: integer constant & conditional expression - * check-known-to-fail - * - * check-error-start - * check-error-end */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/linear/asm-memop.c new/sparse-0.6.1rc2+20191007/validation/linear/asm-memop.c --- old/sparse-0.6.1rc1+20190404/validation/linear/asm-memop.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sparse-0.6.1rc2+20191007/validation/linear/asm-memop.c 2019-10-07 09:46:35.000000000 +0200 @@ -0,0 +1,23 @@ +static int foo(int *p) +{ + asm("op %0" : "=m" (p[0])); + + return p[0]; +} + +/* + * check-name: linear-asm-memop + * check-command: test-linearize $file + * + * check-output-start +foo: +.L0: + <entry-point> + asm "op %0" + out: "=m" (%arg1) + load.32 %r4 <- 0[%arg1] + ret.32 %r4 + + + * check-output-end + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/linear/compound-literal02.c new/sparse-0.6.1rc2+20191007/validation/linear/compound-literal02.c --- old/sparse-0.6.1rc1+20190404/validation/linear/compound-literal02.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/linear/compound-literal02.c 2019-10-07 09:46:35.000000000 +0200 @@ -13,7 +13,6 @@ * check-name: compound-literal02.c * check-command: test-linearize -Wno-decl $file * - * check-known-to-fail * check-output-ignore * check-output-contains: ret\\..*\\$6 */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/preprocessor/preprocessor22.c new/sparse-0.6.1rc2+20191007/validation/preprocessor/preprocessor22.c --- old/sparse-0.6.1rc1+20190404/validation/preprocessor/preprocessor22.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/preprocessor/preprocessor22.c 2019-10-07 09:46:35.000000000 +0200 @@ -20,10 +20,10 @@ * check-command: sparse -E $file * * check-error-start -preprocessor/preprocessor22.c:6:1: error: directive in argument list -preprocessor/preprocessor22.c:8:1: error: directive in argument list -preprocessor/preprocessor22.c:10:1: error: directive in argument list -preprocessor/preprocessor22.c:12:1: error: directive in argument list +preprocessor/preprocessor22.c:6:1: error: directive in macro's argument list +preprocessor/preprocessor22.c:8:1: error: directive in macro's argument list +preprocessor/preprocessor22.c:10:1: error: directive in macro's argument list +preprocessor/preprocessor22.c:12:1: error: directive in macro's argument list * check-error-end * * check-output-start diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sparse-0.6.1rc1+20190404/validation/static_assert.c new/sparse-0.6.1rc2+20191007/validation/static_assert.c --- old/sparse-0.6.1rc1+20190404/validation/static_assert.c 2019-04-04 22:50:29.000000000 +0200 +++ new/sparse-0.6.1rc2+20191007/validation/static_assert.c 2019-10-07 09:46:35.000000000 +0200 @@ -61,11 +61,11 @@ static_assert.c:22:16: error: bad constant expression static_assert.c:25:16: error: bad constant expression static_assert.c:27:16: error: bad constant expression -static_assert.c:35:19: error: bad or missing string literal +static_assert.c:35:19: error: string literal expected for _Static_assert() static_assert.c:37:18: error: bad constant expression -static_assert.c:52:19: error: bad or missing string literal +static_assert.c:52:19: error: string literal expected for _Static_assert() static_assert.c:53:16: error: Expected constant expression static_assert.c:54:16: error: Expected constant expression -static_assert.c:54:17: error: bad or missing string literal +static_assert.c:54:17: error: string literal expected for _Static_assert() * check-error-end */
