diff options
author | Palmer Dabbelt <palmer@rivosinc.com> | 2022-08-16 17:33:12 -0700 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2022-08-16 17:33:12 -0700 |
commit | 8b49b855df3be25489ef82dbdb3cc913f9c4a4ca (patch) | |
tree | 7e3852c3950fae6a46db57b1088c8ce80edfa106 | |
parent | 53eacc1fa688f066a5426f44fbc85710677fc172 (diff) | |
parent | 444345ff84a068d0080493fc56eb8dc9bd19a665 (diff) | |
download | sparse-__archive__.tar.gz |
Merge remote-tracking branch 'palmer/riscv-zicbom' into __archive____archive__
* palmer/riscv-zicbom: (32 commits)
RISC-V: Add support fo the zihintpause extension
RISC-V: Add support for the zicbom extension
inline: free symbol list after use
inline: allocate statement after guards
inline: avoid needless intermediate vars
inline: declaration of the variadic vars is useless
inline: comment about creating node of node on variadics
inline: add testcases for inlining of variadics
fix "unreplaced" warnings caused by using typeof() on inline functions
predefine __ATOMIC_ACQUIRE & friends as weak
allow show_token() on TOKEN_ZERO_IDENT
fix crash when inlining casts of erroneous expressions
cgcc: do not die on '-x assembler'
RISC-V: Remove "g" from the extension list
RISC-V: Remove the unimplemented ISA extensions
RISC-V: Match GCC's semantics for multiple -march instances
RISC-V: don't die() on -march errors, just warn
cast_value: remove error-prone redundant argument
cast_value: assign the new type
fix zero/sign extension of integer character constants
...
-rw-r--r-- | Documentation/release-notes/v0.6.4.rst | 2 | ||||
-rw-r--r-- | builtin.c | 8 | ||||
-rwxr-xr-x | cgcc | 12 | ||||
-rw-r--r-- | dissect.c | 61 | ||||
-rw-r--r-- | evaluate.c | 2 | ||||
-rw-r--r-- | expand.c | 10 | ||||
-rw-r--r-- | expression.c | 9 | ||||
-rw-r--r-- | expression.h | 3 | ||||
-rw-r--r-- | inline.c | 25 | ||||
-rw-r--r-- | options.c | 18 | ||||
-rw-r--r-- | options.h | 2 | ||||
-rw-r--r-- | parse.c | 8 | ||||
-rw-r--r-- | predefine.c | 12 | ||||
-rw-r--r-- | semind.c | 1 | ||||
-rw-r--r-- | sparse.c | 2 | ||||
-rw-r--r-- | target-riscv.c | 65 | ||||
-rw-r--r-- | test-dissect.c | 5 | ||||
-rw-r--r-- | token.h | 2 | ||||
-rw-r--r-- | tokenize.c | 2 | ||||
-rw-r--r-- | validation/builtin-objsize-self-init.c | 11 | ||||
-rw-r--r-- | validation/byte-count-max.c | 28 | ||||
-rw-r--r-- | validation/char-constant-signed.c | 9 | ||||
-rw-r--r-- | validation/char-constant-unsigned.c | 9 | ||||
-rw-r--r-- | validation/inline-early/bug-bad-token.c | 15 | ||||
-rw-r--r-- | validation/inline-early/unreplaced-abstract.c | 28 | ||||
-rw-r--r-- | validation/inline-early/variadic0.c | 13 | ||||
-rw-r--r-- | validation/label-positioning.c | 22 | ||||
-rw-r--r-- | validation/optim/devirtualize0.c | 17 |
28 files changed, 337 insertions, 64 deletions
diff --git a/Documentation/release-notes/v0.6.4.rst b/Documentation/release-notes/v0.6.4.rst index 387870fa..08830bd8 100644 --- a/Documentation/release-notes/v0.6.4.rst +++ b/Documentation/release-notes/v0.6.4.rst @@ -1,4 +1,4 @@ -v0.6.4 (2020-09-06) +v0.6.4 (2021-09-06) =================== Fixes: @@ -546,11 +546,19 @@ static int expand_object_size(struct expression *expr, int cost) // a deref is just intermediate variable // and so the offset needs to be zeroed. if (arg->op == '*') { + struct expression *parent = arg; arg = arg->unop; off = 0; switch (arg->type) { case EXPR_SYMBOL: arg = arg->symbol->initializer; + if (arg == parent) { + // stop at self-initialized vars + // and do not expand them. + arg = NULL; + val = -1; + break; + } continue; default: break; @@ -42,11 +42,10 @@ while (@ARGV) { $nargs = 1; } - # Ignore the extension if '-x c' is given. + # We don't want to run the checker on non-C files. if ($_ eq '-x') { die ("$0: missing argument for $_") if !@ARGV; - die ("$0: invalid argument for $_") if $ARGV[0] ne 'c'; - $do_check = 1; + $do_check = ($ARGV[0] eq 'c'); $nargs = 1; } @@ -292,6 +291,9 @@ sub add_specs { } elsif ($spec eq 'aarch64') { return (' --arch=aarch64' . &float_types (1, 1, 36, [24,8], [53,11], [113,15])); + } elsif ($spec eq 'xtensa') { + return (' --arch=xtensa' . + &float_types (1, 1, 21, [24,8], [53,11], [53,11])); } elsif ($spec eq 'host_os_specs') { my $os = `uname -s`; chomp $os; @@ -319,6 +321,8 @@ sub add_specs { return &add_specs ('x86_64') . ' -mx32'; } elsif ($gccmachine =~ '^x86_64-') { return &add_specs ('x86_64'); + } elsif ($gccmachine =~ '^xtensa-') { + return &add_specs ('xtensa'); } # fall back to uname -m to determine the specifics. @@ -348,6 +352,8 @@ sub add_specs { return &add_specs ('arm'); } elsif ($arch =~ /^(aarch64)$/i) { return &add_specs ('aarch64'); + } elsif ($arch =~ /^(xtensa)$/i) { + return &add_specs ('xtensa'); } } else { die "$0: invalid specs: $spec\n"; @@ -610,6 +610,16 @@ static struct symbol *do_initializer(struct symbol *type, struct expression *exp return type; } +static inline bool is_macro(struct symbol *sym) +{ + return (sym->namespace == NS_MACRO || sym->namespace == NS_UNDEF); +} + +static inline bool is_typedef(struct symbol *sym) +{ + return (sym->namespace == NS_TYPEDEF); +} + static inline struct symbol *do_symbol(struct symbol *sym) { struct symbol *type = base_type(sym); @@ -652,9 +662,58 @@ static void do_sym_list(struct symbol_list *list) DO_LIST(list, sym, do_symbol(sym)); } +static inline bool valid_namespace(enum namespace ns) +{ + return (ns == NS_TYPEDEF || ns == NS_MACRO || ns == NS_UNDEF || ns == NS_STRUCT || ns == NS_SYMBOL); +} + +static void do_file(char *file) +{ + struct symbol_list *res = sparse_keep_tokens(file); + + if (!dissect_show_all_symbols) { + do_sym_list(res); + goto end; + } + + DO_LIST(file_scope->symbols, sym, + if (input_streams[sym->pos.stream].fd != -1 && valid_namespace(sym->namespace)) { + if (is_typedef(sym)) { + sym->kind = 't'; + reporter->r_symdef(sym); + continue; + } + + if (is_macro(sym)) { + sym->kind = 'd'; + reporter->r_symdef(sym); + continue; + } + + if (sym->type == SYM_STRUCT || sym->type == SYM_UNION) { + sym->ctype.base_type = sym; + examine_sym_node(sym, NULL); + continue; + } + + do_symbol(sym); + } + ); + + DO_LIST(global_scope->symbols, sym, + if (input_streams[sym->pos.stream].fd != -1 && valid_namespace(sym->namespace)) { + do_symbol(sym); + } + ); + +end: + /* Drop the tokens for this file after parsing */ + clear_token_alloc(); +} + void dissect(struct reporter *rep, struct string_list *filelist) { reporter = rep; - DO_LIST(filelist, file, do_sym_list(__sparse(file))); + DO_LIST(filelist, file, do_file(file)); } @@ -3555,7 +3555,7 @@ static struct symbol *evaluate_symbol(struct symbol *sym) current_fn = sym; examine_fn_arguments(base_type); - if (!base_type->stmt && base_type->inline_stmt) + if (!base_type->stmt && base_type->inline_stmt && sym->definition) uninline(sym); if (base_type->stmt) evaluate_statement(base_type->stmt); @@ -94,9 +94,9 @@ static long long get_longlong(struct expression *expr) return (value & andmask) | ormask; } -void cast_value(struct expression *expr, struct symbol *newtype, - struct expression *old, struct symbol *oldtype) +void cast_value(struct expression *expr, struct symbol *newtype, struct expression *old) { + struct symbol *oldtype = old->ctype; int old_size = oldtype->bit_size; int new_size = newtype->bit_size; long long value, mask, signmask; @@ -110,11 +110,13 @@ void cast_value(struct expression *expr, struct symbol *newtype, expr->taint = old->taint; if (old_size == new_size) { expr->value = old->value; + expr->ctype = newtype; return; } // expand it to the full "long long" value value = get_longlong(old); + expr->ctype = newtype; Int: // _Bool requires a zero test rather than truncation. @@ -153,6 +155,7 @@ Float: value = (long long)old->fvalue; expr->type = EXPR_VALUE; expr->taint = 0; + expr->ctype = newtype; goto Int; } @@ -168,6 +171,7 @@ Float: expr->fvalue = (float)expr->fvalue; } expr->type = EXPR_FVALUE; + expr->ctype = newtype; } /* Return true if constant shift size is valid */ @@ -872,7 +876,7 @@ static int expand_cast(struct expression *expr) /* Simplify normal integer casts.. */ if (target->type == EXPR_VALUE || target->type == EXPR_FVALUE) { - cast_value(expr, expr->ctype, target, target->ctype); + cast_value(expr, expr->ctype, target); return 0; } return cost + 1; diff --git a/expression.c b/expression.c index 221d7780..727e7056 100644 --- a/expression.c +++ b/expression.c @@ -427,8 +427,15 @@ struct token *primary_expression(struct token *token, struct expression **tree) case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3: expr = alloc_expression(token->pos, EXPR_VALUE); expr->flags = CEF_SET_CHAR; - expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype; get_char_constant(token, &expr->value); + + // TODO: handle 'u8', 'u' & 'U' prefixes. + if (token_type(token) < TOKEN_WIDE_CHAR) { + expr->ctype = &char_ctype; + cast_value(expr, &int_ctype, expr); + } else { + expr->ctype = wchar_ctype; + } token = token->next; break; diff --git a/expression.h b/expression.h index f733c076..8bf40d32 100644 --- a/expression.h +++ b/expression.h @@ -337,7 +337,6 @@ struct token *compound_statement(struct token *, struct statement *); #define constant_expression(token,tree) conditional_expression(token, tree) /* Cast folding of constant values.. */ -void cast_value(struct expression *expr, struct symbol *newtype, - struct expression *old, struct symbol *oldtype); +void cast_value(struct expression *expr, struct symbol *newtype, struct expression *old); #endif @@ -155,6 +155,8 @@ static struct expression * copy_expression(struct expression *expr) /* Cast/sizeof/__alignof__ */ case EXPR_CAST: + if (!expr->cast_expression) + return NULL; if (expr->cast_expression->type == EXPR_INITIALIZER) { struct expression *cast = expr->cast_expression; struct symbol *sym = expr->cast_type; @@ -514,9 +516,8 @@ int inline_function(struct expression *expr, struct symbol *sym) { struct symbol_list * fn_symbol_list; struct symbol *fn = sym->ctype.base_type; - struct expression_list *arg_list = expr->args; - struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND); - struct symbol_list *name_list, *arg_decl; + struct statement *stmt; + struct symbol_list *arg_decl; struct symbol *name; struct expression *arg; @@ -527,8 +528,7 @@ int inline_function(struct expression *expr, struct symbol *sym) if (fn->expanding) return 0; - name_list = fn->arguments; - + stmt = alloc_statement(expr->pos, STMT_COMPOUND); expr->type = EXPR_STATEMENT; expr->statement = stmt; expr->ctype = fn->ctype.base_type; @@ -536,18 +536,22 @@ int inline_function(struct expression *expr, struct symbol *sym) fn_symbol_list = create_symbol_list(sym->inline_symbol_list); arg_decl = NULL; - PREPARE_PTR_LIST(name_list, name); - FOR_EACH_PTR(arg_list, arg) { + PREPARE_PTR_LIST(fn->arguments, name); + FOR_EACH_PTR(expr->args, arg) { struct symbol *a = alloc_symbol(arg->pos, SYM_NODE); - a->ctype.base_type = arg->ctype; if (name) { *a = *name; set_replace(name, a); add_symbol(&fn_symbol_list, a); + a->initializer = arg; + add_symbol(&arg_decl, a); + } else { + // This may create a node of a node but it will + // be resolved later when the corresponding + // STMT_DECLARATION will be evaluated. + a->ctype.base_type = arg->ctype; } - a->initializer = arg; - add_symbol(&arg_decl, a); NEXT_PTR_LIST(name); } END_FOR_EACH_PTR(arg); @@ -563,6 +567,7 @@ int inline_function(struct expression *expr, struct symbol *sym) stmt->inline_fn = sym; unset_replace_list(fn_symbol_list); + free_ptr_list(&fn_symbol_list); return 1; } @@ -64,6 +64,8 @@ int dbg_postorder = 0; int dump_macro_defs = 0; int dump_macros_only = 0; +int dissect_show_all_symbols = 0; + unsigned long fdump_ir; int fhosted = 1; unsigned int fmax_errors = 100; @@ -679,6 +681,19 @@ static const struct flag mflags[] = { static char **handle_switch_m(char *arg, char **next) { + if (!strcmp(arg, "meabi") && next[1] && next[1][0] != '-') { + // clang has such an option with syntax: -meabi <arg> + // It's used by the kernel for armv7. + // GCC has the same option but with no argument. + // Parse it here to consume the possible argument. + static const char *valid[] = { "gnu", "4", "5", "default", NULL }; + int i; + for (i = 0; valid[i]; i++) { + if (!strcmp(next[1], valid[i])) + return ++next; + } + } + if (!strcmp(arg, "multiarch-dir")) { return handle_multiarch_dir(arg, next); } else { @@ -952,6 +967,9 @@ static char **handle_param(char *arg, char **next) if (!value) die("missing argument for --param option"); + if (!strcmp(value, "dissect-show-all-symbols")) + dissect_show_all_symbols = 1; + return next; } @@ -70,6 +70,8 @@ extern int dbg_postorder; extern int dump_macro_defs; extern int dump_macros_only; +extern int dissect_show_all_symbols; + extern unsigned long fdump_ir; extern int fhosted; extern unsigned int fmax_errors; @@ -903,8 +903,7 @@ static void cast_enum_list(struct symbol_list *list, struct symbol *base_type) expr->ctype = &int_ctype; continue; } - cast_value(expr, base_type, expr, ctype); - expr->ctype = base_type; + cast_value(expr, base_type, expr); } END_FOR_EACH_PTR(sym); } @@ -2329,6 +2328,11 @@ static inline struct token *case_statement(struct token *token, struct statement stmt->type = STMT_CASE; token = expect(token, ':', "after default/case"); add_case_statement(stmt); + if (match_op(token, '}')) { + warning(token->pos, "statement expected after case label"); + stmt->case_statement = alloc_statement(token->pos, STMT_NONE); + return token; + } return statement(token, &stmt->case_statement); } diff --git a/predefine.c b/predefine.c index 98e38a04..5b0f0caf 100644 --- a/predefine.c +++ b/predefine.c @@ -179,12 +179,12 @@ void predefined_macros(void) if (arch_target->has_int128) predefined_sizeof("INT128", "", 128); - predefine("__ATOMIC_RELAXED", 0, "0"); - predefine("__ATOMIC_CONSUME", 0, "1"); - predefine("__ATOMIC_ACQUIRE", 0, "3"); - predefine("__ATOMIC_RELEASE", 0, "4"); - predefine("__ATOMIC_ACQ_REL", 0, "7"); - predefine("__ATOMIC_SEQ_CST", 0, "8"); + predefine("__ATOMIC_RELAXED", 1, "0"); + predefine("__ATOMIC_CONSUME", 1, "1"); + predefine("__ATOMIC_ACQUIRE", 1, "3"); + predefine("__ATOMIC_RELEASE", 1, "4"); + predefine("__ATOMIC_ACQ_REL", 1, "7"); + predefine("__ATOMIC_SEQ_CST", 1, "8"); predefine("__ORDER_LITTLE_ENDIAN__", 1, "1234"); predefine("__ORDER_BIG_ENDIAN__", 1, "4321"); @@ -329,6 +329,7 @@ done: optind--; sparse_initialize(argc - optind, argv + optind, &semind_filelist); + dissect_show_all_symbols = 1; } static void parse_cmdline_rm(int argc, char **argv) @@ -165,7 +165,7 @@ static void check_byte_count(struct instruction *insn, pseudo_t count) static void check_memset(struct instruction *insn) { - check_byte_count(insn, ptr_list_nth(insn->arguments, 3)); + check_byte_count(insn, ptr_list_nth(insn->arguments, 2)); } #define check_memcpy check_memset diff --git a/target-riscv.c b/target-riscv.c index ff4dfba3..23d28d0e 100644 --- a/target-riscv.c +++ b/target-riscv.c @@ -5,20 +5,22 @@ #include <string.h> #include <stdio.h> -#define RISCV_32BIT (1 << 0) -#define RISCV_64BIT (1 << 1) -#define RISCV_MUL (1 << 2) -#define RISCV_DIV (1 << 3) -#define RISCV_ATOMIC (1 << 4) -#define RISCV_FLOAT (1 << 5) -#define RISCV_DOUBLE (1 << 6) -#define RISCV_FDIV (1 << 7) -#define RISCV_COMP (1 << 8) -#define RISCV_EMBD (1 << 9) -#define RISCV_FPU (RISCV_FLOAT|RISCV_DOUBLE|RISCV_FDIV) -#define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU) -#define RISCV_ZICSR (1 << 10) -#define RISCV_ZIFENCEI (1 << 11) +#define RISCV_32BIT (1 << 0) +#define RISCV_64BIT (1 << 1) +#define RISCV_MUL (1 << 2) +#define RISCV_DIV (1 << 3) +#define RISCV_ATOMIC (1 << 4) +#define RISCV_FLOAT (1 << 5) +#define RISCV_DOUBLE (1 << 6) +#define RISCV_FDIV (1 << 7) +#define RISCV_COMP (1 << 8) +#define RISCV_EMBD (1 << 9) +#define RISCV_FPU (RISCV_FLOAT|RISCV_DOUBLE|RISCV_FDIV) +#define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU) +#define RISCV_ZICSR (1 << 10) +#define RISCV_ZIFENCEI (1 << 11) +#define RISCV_ZICBOM (1 << 12) +#define RISCV_ZIHINTPAUSE (1 << 13) static unsigned int riscv_flags; @@ -34,37 +36,34 @@ static void parse_march_riscv(const char *arg) { "rv64i", RISCV_64BIT }, { "rv64g", RISCV_64BIT|RISCV_GENERIC }, }, extensions[] = { - { "m", RISCV_MUL|RISCV_DIV }, - { "a", RISCV_ATOMIC }, - { "f", RISCV_FLOAT|RISCV_FDIV|RISCV_ZICSR }, - { "d", RISCV_DOUBLE|RISCV_FDIV|RISCV_ZICSR }, - { "c", RISCV_COMP }, - { "_zicsr", RISCV_ZICSR }, - { "_zifencei", RISCV_ZIFENCEI }, + { "m", RISCV_MUL|RISCV_DIV }, + { "a", RISCV_ATOMIC }, + { "f", RISCV_FLOAT|RISCV_FDIV|RISCV_ZICSR }, + { "d", RISCV_DOUBLE|RISCV_FDIV|RISCV_ZICSR }, + { "c", RISCV_COMP }, + { "_zicsr", RISCV_ZICSR }, + { "_zifencei", RISCV_ZIFENCEI }, + { "_zicbom", RISCV_ZICBOM }, + { "_zihintpause", RISCV_ZIHINTPAUSE }, }; int i; + // Each -march=.. options entirely overrides previous ones + riscv_flags = 0; + for (i = 0; i < ARRAY_SIZE(basic_sets); i++) { const char *pat = basic_sets[i].pattern; size_t len = strlen(pat); if (!strncmp(arg, pat, len)) { - riscv_flags = basic_sets[i].flags; + riscv_flags |= basic_sets[i].flags; arg += len; goto ext; } } unknown: - /* - * This behaves like do_warn() / do_error(), but we don't have a - * position so it's just inline here. - */ - fflush(stdout); - fprintf(stderr, "%s: invalid argument to '-march': '%s'\n", - Wsparse_error == FLAG_ON ? "error" : "warning", arg); - if (Wsparse_error == FLAG_ON) - has_error |= ERROR_CURR_PHASE; + fprintf(stderr, "WARNING: invalid argument to '-march': '%s'\n", arg); return; ext: @@ -136,6 +135,10 @@ static void predefine_riscv(const struct target *self) predefine("__riscv_zicsr", 1, "1"); if (riscv_flags & RISCV_ZIFENCEI) predefine("__riscv_zifencei", 1, "1"); + if (riscv_flags & RISCV_ZICBOM) + predefine("__riscv_zicbom", 1, "1"); + if (riscv_flags & RISCV_ZIHINTPAUSE) + predefine("__riscv_zihintpause", 1, "1"); if (cmodel) predefine_strong("__riscv_cmodel_%s", cmodel); diff --git a/test-dissect.c b/test-dissect.c index 58b3e633..65b205f8 100644 --- a/test-dissect.c +++ b/test-dissect.c @@ -57,11 +57,14 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym) show_typename(sym->ctype.base_type)); switch (sym->kind) { + case 'd': + break; case 's': if (sym->type == SYM_STRUCT || sym->type == SYM_UNION) break; goto err; - + case 't': + break; case 'f': if (sym->type != SYM_BAD && sym->ctype.base_type->type != SYM_FN) goto err; @@ -201,7 +201,7 @@ struct token { static inline struct token *containing_token(struct token **p) { - void *addr = (char *)p - ((char *)&((struct token *)0)->next - (char *)0); + void *addr = (char *)p - offsetof(struct token, next); return addr; } @@ -201,6 +201,7 @@ const char *show_token(const struct token *token) return "end-of-input"; case TOKEN_IDENT: + case TOKEN_ZERO_IDENT: return show_ident(token->ident); case TOKEN_NUMBER: @@ -259,6 +260,7 @@ const char *quote_token(const struct token *token) return "syntax error"; case TOKEN_IDENT: + case TOKEN_ZERO_IDENT: return show_ident(token->ident); case TOKEN_NUMBER: diff --git a/validation/builtin-objsize-self-init.c b/validation/builtin-objsize-self-init.c new file mode 100644 index 00000000..77e3da43 --- /dev/null +++ b/validation/builtin-objsize-self-init.c @@ -0,0 +1,11 @@ +static void f(void) +{ + void *param = param; + __builtin_object_size(param, 0); +} + +/* + * check-name: builtin-objsize-self-init + * check-timeout: + * check-error-end + */ diff --git a/validation/byte-count-max.c b/validation/byte-count-max.c new file mode 100644 index 00000000..0555a505 --- /dev/null +++ b/validation/byte-count-max.c @@ -0,0 +1,28 @@ +typedef unsigned long int size_t; +typedef unsigned long ulong; + +extern void *memset(void *s, int c, size_t n); +extern void *memcpy(void *dest, void *src, size_t n); +extern ulong copy_to_user(void *to, const void *from, ulong count); +extern ulong copy_from_user(void *to, const void *from, ulong count); + +static void func (char *s) +{ + char d[250000]; + + memset(d, 0, 250000); + memcpy(d, s, 250000); + copy_to_user(s, d, 250000); + copy_from_user(d, s, 250000); +} + +/* + * check-name: byte-count-max + * + * check-error-start +byte-count-max.c:13:15: warning: memset with byte count of 250000 +byte-count-max.c:14:15: warning: memcpy with byte count of 250000 +byte-count-max.c:15:21: warning: copy_to_user with byte count of 250000 +byte-count-max.c:16:23: warning: copy_from_user with byte count of 250000 + * check-error-end + */ diff --git a/validation/char-constant-signed.c b/validation/char-constant-signed.c new file mode 100644 index 00000000..be0fd5ce --- /dev/null +++ b/validation/char-constant-signed.c @@ -0,0 +1,9 @@ +int test(void) { return '\377' == -1; } + +/* + * check-name: char-constant-signed + * check-command: test-linearize -Wno-decl -fsigned-char $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/char-constant-unsigned.c b/validation/char-constant-unsigned.c new file mode 100644 index 00000000..d5642b16 --- /dev/null +++ b/validation/char-constant-unsigned.c @@ -0,0 +1,9 @@ +int test(void) { return '\377' == 255; } + +/* + * check-name: char-constant-unsigned + * check-command: test-linearize -Wno-decl -funsigned-char $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/inline-early/bug-bad-token.c b/validation/inline-early/bug-bad-token.c new file mode 100644 index 00000000..9049bdb4 --- /dev/null +++ b/validation/inline-early/bug-bad-token.c @@ -0,0 +1,15 @@ +inline void fun(int x) +{ + (typeof(@)) x; +} + +void foo(void) +{ + fun; +} + +/* + * check-name: bug-bad-token + * check-exit-value: 0 + * check-error-ignore + */ diff --git a/validation/inline-early/unreplaced-abstract.c b/validation/inline-early/unreplaced-abstract.c new file mode 100644 index 00000000..e38cd668 --- /dev/null +++ b/validation/inline-early/unreplaced-abstract.c @@ -0,0 +1,28 @@ +static inline void f0(void) { } +static inline long f1(long a) { return a + 1;} + +_Static_assert([typeof(f0)] != [typeof(f1)]); + + +static inline void g0(void) { } +static inline long g1(long a) { return a + 1;} + +extern long goo(long a); +long goo(long a) +{ + g0(); + return g1(a); +} + +_Static_assert([typeof(g0)] != [typeof(g1)]); + +extern long moo(long a); +long moo(long a) +{ + typeof(f1) *f = g1; + return f(a); +} + +/* + * check-name: unreplaced-abstract + */ diff --git a/validation/inline-early/variadic0.c b/validation/inline-early/variadic0.c new file mode 100644 index 00000000..566e129f --- /dev/null +++ b/validation/inline-early/variadic0.c @@ -0,0 +1,13 @@ +static inline void fun(const char *fmt, ...) +{ +} + +void main(void) +{ + fun("abc", 0); // will be a SYM_BASETYPE + fun("ijk", (const int)1); // will be a SYM_NODE +} + +/* + * check-name: variadic0 + */ diff --git a/validation/label-positioning.c b/validation/label-positioning.c new file mode 100644 index 00000000..583661ca --- /dev/null +++ b/validation/label-positioning.c @@ -0,0 +1,22 @@ +extern int someval(void); + +static void func (int x) +{ + if (x > someval()) + goto end; + switch (x) { case 0: } + switch (x) { case 1 ... 9: } + switch (x) { default: } +end: +} + +/* + * check-name: label-positioning + * + * check-error-start +label-positioning.c:7:30: warning: statement expected after case label +label-positioning.c:8:36: warning: statement expected after case label +label-positioning.c:9:31: warning: statement expected after case label +label-positioning.c:11:1: warning: statement expected after label + * check-error-end + */ diff --git a/validation/optim/devirtualize0.c b/validation/optim/devirtualize0.c new file mode 100644 index 00000000..7079e790 --- /dev/null +++ b/validation/optim/devirtualize0.c @@ -0,0 +1,17 @@ +static inline long f1(long x) { return x + 1;} + +extern long foo(long a); +long foo(long a) +{ + typeof(f1) *f = f1; + return f(a); +} + +/* + * check-name: devirtualize0 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: call\\. + */ |