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, &ltype);
        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
  */


Reply via email to