diff options
| -rw-r--r-- | Documentation/test-suite | 8 | ||||
| -rw-r--r-- | Makefile | 10 | ||||
| -rwxr-xr-x | cgcc | 11 | ||||
| -rw-r--r-- | evaluate.c | 2 | ||||
| -rw-r--r-- | graph.c | 8 | ||||
| -rw-r--r-- | lib.c | 25 | ||||
| -rw-r--r-- | lib.h | 1 | ||||
| -rw-r--r-- | linearize.h | 4 | ||||
| -rw-r--r-- | liveness.c | 2 | ||||
| -rw-r--r-- | parse.c | 14 | ||||
| -rw-r--r-- | pre-process.c | 4 | ||||
| -rw-r--r-- | simplify.c | 3 | ||||
| -rw-r--r-- | sparse.c | 33 | ||||
| -rw-r--r-- | symbol.c | 14 | ||||
| -rw-r--r-- | symbol.h | 4 | ||||
| -rw-r--r-- | validation/compound-sizes.c | 88 | ||||
| -rw-r--r-- | validation/linear/range-op.c | 31 | ||||
| -rw-r--r-- | validation/preprocessor/phase2-backslash.c (renamed from validation/phase2/backslash) | 29 | ||||
| -rw-r--r-- | validation/preprocessor/phase3-comments.c (renamed from validation/phase3/comments) | 12 | ||||
| -rw-r--r-- | validation/range-syntax.c | 23 | ||||
| -rwxr-xr-x | validation/test-suite | 26 | ||||
| -rw-r--r-- | validation/typedef-redef-c89.c | 13 | ||||
| -rw-r--r-- | validation/typedef-redef.c | 13 | ||||
| -rw-r--r-- | validation/typediff-arraysize.c | 12 | ||||
| -rw-r--r-- | validation/typediff-enum.c | 34 |
25 files changed, 385 insertions, 39 deletions
diff --git a/Documentation/test-suite b/Documentation/test-suite index 1315dbd6..bf4518a2 100644 --- a/Documentation/test-suite +++ b/Documentation/test-suite @@ -27,6 +27,14 @@ check-arch-only: <arch[|...]> Ignore the test if the current architecture (as returned by 'uname -m') match or not one of the archs given in the pattern. +check-assert: <condition> + Ignore the test if the given condition is false when evaluated as a + static assertion (_Static_assert). + +check-cpp-if: <condition> + Ignore the test if the given condition is false when evaluated + by sparse's pre-processor. + check-exit-value: <value> The expected exit value of check-command. It defaults to 0. @@ -143,7 +143,11 @@ endif LLVM_CONFIG:=llvm-config HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes') ifeq ($(HAVE_LLVM),yes) -ifeq ($(shell uname -m | grep -q '\(i[3456]86\|x86\|amd64\)' && echo ok),ok) +arch := $(shell uname -m) +ifeq (${MULTIARCH_TRIPLET},x86_64-linux-gnux32) +arch := x32 +endif +ifneq ($(filter ${arch},i386 i486 i586 i686 x86_64 amd64),) LLVM_VERSION:=$(shell $(LLVM_CONFIG) --version) ifeq ($(shell expr "$(LLVM_VERSION)" : '[3-9]\.'),2) LLVM_PROGS := sparse-llvm @@ -161,7 +165,7 @@ else $(warning LLVM 3.0 or later required. Your system has version $(LLVM_VERSION) installed.) endif else -$(warning sparse-llvm disabled on $(shell uname -m)) +$(warning sparse-llvm disabled on ${arch}) endif else $(warning Your system does not have llvm, disabling sparse-llvm) @@ -201,7 +205,7 @@ cflags += $($(*)-cflags) $(CPPFLAGS) $(CFLAGS) selfcheck: $(OBJS:.o=.sc) -SPARSE_VERSION:=$(shell git describe 2>/dev/null || echo '$(VERSION)') +SPARSE_VERSION:=$(shell git describe --dirty 2>/dev/null || echo '$(VERSION)') lib.o: version.h version.h: FORCE @echo '#define SPARSE_VERSION "$(SPARSE_VERSION)"' > version.h.tmp @@ -265,10 +265,7 @@ sub add_specs { " -D'__declspec(x)=__attribute__((x))'"; } elsif ($spec eq 'i86') { return (' -D__i386=1 -D__i386__=1' . - &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . - &float_types (1, 1, 21, [24,8], [53,11], [64,15]) . - &define_size_t ($m64 ? "long unsigned int" : "unsigned int") . - ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4')); + &float_types (1, 1, 21, [24,8], [53,11], [64,15])); } elsif ($spec eq 'sparc') { return (' -D__sparc=1 -D__sparc__=1' . &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . @@ -282,11 +279,7 @@ sub add_specs { &define_size_t ("long unsigned int") . ' -D__SIZEOF_POINTER__=8'); } elsif ($spec eq 'x86_64') { - return (' -D__x86_64=1 -D__x86_64__=1' . ($m32 ? '' : ' -D__LP64__=1') . - &integer_types (8, 16, 32, $m32 ? 32 : 64, 64, 128) . - &float_types (1, 1, 33, [24,8], [53,11], [113,15]) . - &define_size_t ($m32 ? "unsigned int" : "long unsigned int") . - ' -D__SIZEOF_POINTER__=' . ($m32 ? '4' : '8')); + return &float_types (1, 1, 33, [24,8], [53,11], [113,15]); } elsif ($spec eq 'ppc') { return (' -D__powerpc__=1 -D_BIG_ENDIAN -D_STRING_ARCH_unaligned=1' . &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) . @@ -3291,7 +3291,7 @@ struct symbol *evaluate_expression(struct expression *expr) return NULL; } -static void check_duplicates(struct symbol *sym) +void check_duplicates(struct symbol *sym) { int declared = 0; struct symbol *next = sym; @@ -78,15 +78,15 @@ static void graph_ep(struct entrypoint *ep) continue; switch(insn->opcode) { case OP_STORE: - if (insn->symbol->type == PSEUDO_SYM) { - printf("%s store(%s)", s, show_ident(insn->symbol->sym->ident)); + if (insn->src->type == PSEUDO_SYM) { + printf("%s store(%s)", s, show_ident(insn->src->sym->ident)); s = ","; } break; case OP_LOAD: - if (insn->symbol->type == PSEUDO_SYM) { - printf("%s load(%s)", s, show_ident(insn->symbol->sym->ident)); + if (insn->src->type == PSEUDO_SYM) { + printf("%s load(%s)", s, show_ident(insn->src->sym->ident)); s = ","; } break; @@ -259,6 +259,7 @@ int dump_macro_defs = 0; int dbg_entry = 0; int dbg_dead = 0; +int dbg_compound = 0; unsigned long fdump_ir; int fmem_report = 0; @@ -276,12 +277,17 @@ static enum { STANDARD_C89, STANDARD_GNU89, STANDARD_GNU99, } standard = STANDARD_GNU89; -#define ARCH_LP32 0 -#define ARCH_LP64 1 -#define ARCH_LLP64 2 +enum { + ARCH_LP32, + ARCH_X32, + ARCH_LP64, + ARCH_LLP64, +}; #ifdef __LP64__ #define ARCH_M64_DEFAULT ARCH_LP64 +#elif defined(__x86_64__) || defined(__x86_64) +#define ARCH_M64_DEFAULT ARCH_X32 #else #define ARCH_M64_DEFAULT ARCH_LP32 #endif @@ -425,6 +431,8 @@ static char **handle_switch_m(char *arg, char **next) arch_m64 = ARCH_LP64; } else if (!strcmp(arg, "m32")) { arch_m64 = ARCH_LP32; + } else if (!strcmp(arg, "mx32")) { + arch_m64 = ARCH_X32; } else if (!strcmp(arg, "msize-llp64")) { arch_m64 = ARCH_LLP64; } else if (!strcmp(arg, "msize-long")) { @@ -442,6 +450,11 @@ static char **handle_switch_m(char *arg, char **next) static void handle_arch_m64_finalize(void) { switch (arch_m64) { + case ARCH_X32: + max_int_alignment = 8; + add_pre_buffer("#weak_define __ILP32__ 1\n"); + add_pre_buffer("#weak_define _ILP32 1\n"); + goto case_x86_64; case ARCH_LP32: /* default values */ return; @@ -463,8 +476,11 @@ static void handle_arch_m64_finalize(void) case_64bit_common: bits_in_pointer = 64; pointer_alignment = 8; -#ifdef __x86_64__ + /* fall through */ + case_x86_64: +#if defined(__x86_64__) || defined(__x86_64) add_pre_buffer("#weak_define __x86_64__ 1\n"); + add_pre_buffer("#weak_define __x86_64 1\n"); #endif break; } @@ -719,6 +735,7 @@ static char **handle_switch_W(char *arg, char **next) static struct flag debugs[] = { { "entry", &dbg_entry}, { "dead", &dbg_dead}, + { "compound", &dbg_compound}, }; @@ -168,6 +168,7 @@ extern int dump_macro_defs; extern int dbg_entry; extern int dbg_dead; +extern int dbg_compound; extern unsigned int fmax_warnings; extern int fmem_report; diff --git a/linearize.h b/linearize.h index 8790b7e5..db4a67f3 100644 --- a/linearize.h +++ b/linearize.h @@ -117,8 +117,10 @@ struct instruction { pseudo_t base; unsigned from, len; }; - struct /* setval and symaddr */ { + struct /* symaddr */ { pseudo_t symbol; /* Subtle: same offset as "src" !! */ + }; + struct /* setval */ { struct expression *val; }; struct /* setfval */ { @@ -71,7 +71,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction * break; /* Uni */ - case OP_NOT: case OP_NEG: + case OP_NOT: case OP_NEG: case OP_FNEG: USES(src1); DEFINES(target); break; @@ -458,6 +458,11 @@ static struct init_keyword { { "__builtin_ms_va_list", NS_TYPEDEF, .type = &ptr_ctype, .op = &spec_op }, { "__int128_t", NS_TYPEDEF, .type = &lllong_ctype, .op = &spec_op }, { "__uint128_t",NS_TYPEDEF, .type = &ulllong_ctype, .op = &spec_op }, + { "_Float32", NS_TYPEDEF, .type = &float32_ctype, .op = &spec_op }, + { "_Float32x", NS_TYPEDEF, .type = &float32x_ctype, .op = &spec_op }, + { "_Float64", NS_TYPEDEF, .type = &float64_ctype, .op = &spec_op }, + { "_Float64x", NS_TYPEDEF, .type = &float64x_ctype, .op = &spec_op }, + { "_Float128", NS_TYPEDEF, .type = &float128_ctype, .op = &spec_op }, /* Extended types */ { "typeof", NS_TYPEDEF, .op = &typeof_op }, @@ -2367,11 +2372,14 @@ static struct token *parse_context_statement(struct token *token, struct stateme static struct token *parse_range_statement(struct token *token, struct statement *stmt) { stmt->type = STMT_RANGE; - token = assignment_expression(token->next, &stmt->range_expression); + token = token->next; + token = expect(token, '(', "after __range__ statement"); + token = assignment_expression(token, &stmt->range_expression); token = expect(token, ',', "after range expression"); token = assignment_expression(token, &stmt->range_low); token = expect(token, ',', "after low range"); token = assignment_expression(token, &stmt->range_high); + token = expect(token, ')', "after range statement"); return expect(token, ';', "after range statement"); } @@ -2888,6 +2896,10 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis if (decl->same_symbol) { decl->definition = decl->same_symbol->definition; decl->op = decl->same_symbol->op; + if (is_typedef) { + // TODO: handle -std=c89 --pedantic + check_duplicates(decl); + } } if (!match_op(token, ',')) diff --git a/pre-process.c b/pre-process.c index c6c6cdad..7d335ab0 100644 --- a/pre-process.c +++ b/pre-process.c @@ -848,6 +848,10 @@ static void set_stream_include_path(struct stream *stream) includepath[0] = path; } +#ifndef PATH_MAX +#define PATH_MAX 4096 // for Hurd where it's not defined +#endif + static int try_include(const char *path, const char *filename, int flen, struct token **where, const char **next_path) { int fd; @@ -350,6 +350,7 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo) kill_use(&insn->src2); case OP_NOT: case OP_NEG: + case OP_FNEG: case OP_SYMADDR: case OP_CAST: case OP_SCAST: @@ -1208,7 +1209,7 @@ int simplify_instruction(struct instruction *insn) case OP_LSR: case OP_ASR: return simplify_binop(insn); - case OP_NOT: case OP_NEG: + case OP_NOT: case OP_NEG: case OP_FNEG: return simplify_unop(insn); case OP_LOAD: if (!has_users(insn->target)) @@ -274,6 +274,37 @@ static void check_context(struct entrypoint *ep) check_bb_context(ep, ep->entry->bb, in_context, out_context); } +/* list_compound_symbol - symbol info for arrays, structures, unions */ +static void list_compound_symbol(struct symbol *sym) +{ + struct symbol *base; + + /* Only show symbols that have a positive size */ + if (sym->bit_size <= 0) + return; + if (!sym->ctype.base_type) + return; + /* Don't show unnamed types */ + if (!sym->ident) + return; + + if (sym->type == SYM_NODE) + base = sym->ctype.base_type; + else + base = sym; + switch (base->type) { + case SYM_STRUCT: case SYM_UNION: case SYM_ARRAY: + break; + default: + return; + } + + info(sym->pos, "%s: compound size %u, alignment %lu", + show_typename(sym), + bits_to_bytes(sym->bit_size), + sym->ctype.alignment); +} + static void check_symbols(struct symbol_list *list) { struct symbol *sym; @@ -289,6 +320,8 @@ static void check_symbols(struct symbol_list *list) check_context(ep); } + if (dbg_compound) + list_compound_symbol(sym); } END_FOR_EACH_PTR(sym); if (Wsparse_error && die_if_error) @@ -696,6 +696,9 @@ struct symbol bool_ctype, void_ctype, type_ctype, string_ctype, ptr_ctype, lazy_ptr_ctype, incomplete_ctype, label_ctype, bad_ctype, null_ctype; +struct symbol float32_ctype, float32x_ctype; +struct symbol float64_ctype, float64x_ctype; +struct symbol float128_ctype; struct symbol const_void_ctype, const_char_ctype; struct symbol const_ptr_ctype, const_string_ctype; @@ -719,6 +722,11 @@ void init_symbols(void) init_builtins(stream); } +// For fix-sized types +static int bits_in_type32 = 32; +static int bits_in_type64 = 64; +static int bits_in_type128 = 128; + #define MOD_ESIGNED (MOD_SIGNED | MOD_EXPLICITLY_SIGNED) #define MOD_LL (MOD_LONG | MOD_LONGLONG) #define MOD_LLL MOD_LONGLONGLONG @@ -759,6 +767,12 @@ static const struct ctype_declare { { &double_ctype, SYM_BASETYPE, MOD_LONG, &bits_in_double, &max_fp_alignment, &fp_type }, { &ldouble_ctype, SYM_BASETYPE, MOD_LONG | MOD_LONGLONG, &bits_in_longdouble, &max_fp_alignment, &fp_type }, + { &float32_ctype, SYM_BASETYPE, 0, &bits_in_type32, &max_fp_alignment, &fp_type }, + { &float32x_ctype, SYM_BASETYPE, MOD_LONG, &bits_in_double, &max_fp_alignment, &fp_type }, + { &float64_ctype, SYM_BASETYPE, 0, &bits_in_type64, &max_fp_alignment, &fp_type }, + { &float64x_ctype, SYM_BASETYPE, MOD_LONG | MOD_LONGLONG, &bits_in_longdouble, &max_fp_alignment, &fp_type }, + { &float128_ctype, SYM_BASETYPE, 0, &bits_in_type128, &max_alignment, &fp_type }, + { &string_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &char_ctype }, { &ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype }, { &null_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype }, @@ -267,6 +267,9 @@ extern struct symbol bool_ctype, void_ctype, type_ctype, string_ctype, ptr_ctype, lazy_ptr_ctype, incomplete_ctype, label_ctype, bad_ctype, null_ctype; +extern struct symbol float32_ctype, float32x_ctype; +extern struct symbol float64_ctype, float64x_ctype; +extern struct symbol float128_ctype; extern struct symbol const_void_ctype, const_char_ctype; extern struct symbol const_ptr_ctype, const_string_ctype; @@ -311,6 +314,7 @@ extern const char* get_type_name(enum type type); extern void debug_symbol(struct symbol *); extern void merge_type(struct symbol *sym, struct symbol *base_type); extern void check_declaration(struct symbol *sym); +extern void check_duplicates(struct symbol *sym); static inline int valid_type(const struct symbol *ctype) { diff --git a/validation/compound-sizes.c b/validation/compound-sizes.c new file mode 100644 index 00000000..d8ccf605 --- /dev/null +++ b/validation/compound-sizes.c @@ -0,0 +1,88 @@ +// This tests sparse "-vcompound" output. +#define NULL ((void*)0) +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +// Do not list functions. +static int do_nothing(void) +{} + +// no: +static inline int zero(void) +{ + return 0 / 1; +} + +// no: +struct inventory { + unsigned char description[64]; + unsigned char department[64]; + uint32_t dept_number; + uint32_t item_cost; + uint64_t stock_number; + uint32_t tally[12]; // per month +}; + +// no +static struct inventory *get_inv(uint64_t stocknum) +{ + return NULL; +} + +// no +union un { + struct inventory inv; + unsigned char bytes[0]; +}; + +// yes +static union un un; + +// yes +static struct inventory inven[100]; + +// no +typedef struct inventory inventory_t; + +// no +static struct inventory *invptr; + +// yes +static inventory_t invent[10]; + +// no +static float floater; +static double double_float; + +// yes +static float floats[42]; +static double doubles[84]; + +// no +int main(void) +{ + // no, these are not global. + struct inventory inv[10]; + inventory_t invt[10]; + // what about statics? + static struct inventory invtop; + static inventory_t inv_top; + static uint64_t stocknums[100]; + + invptr = get_inv(42000); + return 0; +} + +/* + * check-name: compound-sizes + * check-command: sparse -vcompound $file + * check-assert: _Alignof(long long) == 8 + * + * check-error-start +compound-sizes.c:39:17: union un static [toplevel] un: compound size 192, alignment 8 +compound-sizes.c:42:25: struct inventory static [toplevel] inven[100]: compound size 19200, alignment 8 +compound-sizes.c:51:33: struct inventory static [toplevel] [usertype] invent[10]: compound size 1920, alignment 8 +compound-sizes.c:58:25: float static [toplevel] floats[42]: compound size 168, alignment 4 +compound-sizes.c:59:25: double static [toplevel] doubles[84]: compound size 672, alignment 8 + * check-error-end + */ diff --git a/validation/linear/range-op.c b/validation/linear/range-op.c new file mode 100644 index 00000000..4472bb33 --- /dev/null +++ b/validation/linear/range-op.c @@ -0,0 +1,31 @@ +static void foo(int a) +{ + __range__(a, 0, 8); +} + +static void bar(int a, int b, int c) +{ + __range__(a, b, c); +} + +/* + * check-name: range-op + * check-command: test-linearize -Wno-decl $file + * + * check-output-start +foo: +.L0: + <entry-point> + range-check %arg1 between $0..$8 + ret + + +bar: +.L2: + <entry-point> + range-check %arg1 between %arg2..%arg3 + ret + + + * check-output-end + */ diff --git a/validation/phase2/backslash b/validation/preprocessor/phase2-backslash.c index 29c85b4d..21d94d7d 100644 --- a/validation/phase2/backslash +++ b/validation/preprocessor/phase2-backslash.c @@ -17,11 +17,26 @@ * the rest of tokenizer. */ +/* + * check-name: phase2-backslash + * check-command: sparse -E $file + * + * check-output-start + +"\a" +1 +D +'\a' + * check-output-end + * + * check-error-start +preprocessor/phase2-backslash.c:68:0: warning: backslash-newline at end of file + * check-error-end + */ + #define A(x) #x #define B(x) A(x) /* This should result in "\a" */ -/* XXX: currently sparse produces "a" */ -/* Partially fixed: now it gives "\\a", which is a separate problem */ B(\a) #define C\ @@ -32,31 +47,21 @@ C #define D\ 1 /* And this should give D, since '\n' is removed and we get no whitespace */ -/* XXX: currently sparse produces 1 */ -/* Fixed */ D #define E '\\ a' /* This should give '\a' - with no warnings issued */ -/* XXX: currently sparse complains a lot and ends up producing a */ -/* Fixed */ E /* This should give nothing */ -/* XXX: currently sparse produces more junk */ -/* Fixed */ // junk \ more junk /* This should also give nothing */ -/* XXX: currently sparse produces / * comment * / */ -/* Fixed */ /\ * comment *\ / /* And this should complain since final newline should not be eaten by '\\' */ -/* XXX: currently sparse does not notice */ -/* Fixed */ \ diff --git a/validation/phase3/comments b/validation/preprocessor/phase3-comments.c index 8f51a307..7106b480 100644 --- a/validation/phase3/comments +++ b/validation/preprocessor/phase3-comments.c @@ -3,7 +3,15 @@ */ /* This should give nothing */ -/* XXX: currently sparse produces Y */ -/* Fixed */ #define X /* */ Y + +/* + * check-name: phase3-comments + * check-command: sparse -E $file + * + * check-output-start + + + * check-output-end + */ diff --git a/validation/range-syntax.c b/validation/range-syntax.c new file mode 100644 index 00000000..c43fff0e --- /dev/null +++ b/validation/range-syntax.c @@ -0,0 +1,23 @@ + +static void ok(int a, int b, int c) +{ + __range__(a, 0, 8); + __range__(a, b, c); +} + +static void ko(int a, int b, int c) +{ + __range__ a, 0, 8; + __range__ a, b, c; +} + +/* + * check-name: range syntax + * + * check-error-start +range-syntax.c:10:19: error: Expected ( after __range__ statement +range-syntax.c:10:19: error: got a +range-syntax.c:11:19: error: Expected ( after __range__ statement +range-syntax.c:11:19: error: got a + * check-error-end + */ diff --git a/validation/test-suite b/validation/test-suite index 4fdc9e9f..04607a3e 100755 --- a/validation/test-suite +++ b/validation/test-suite @@ -79,6 +79,8 @@ get_tag_value() check_output_pattern=0 check_arch_ignore="" check_arch_only="" + check_assert="" + check_cpp_if="" lines=$(grep 'check-[a-z-]*' $1 | \ sed -e 's/^.*\(check-[a-z-]*:*\) *\(.*\)$/\1 \2/') @@ -102,6 +104,8 @@ get_tag_value() check_arch_ignore="$val" ;; check-arch-only:) arch=$(uname -m) check_arch_only="$val" ;; + check-assert:) check_assert="$val" ;; + check-cpp-if:) check_cpp_if="$val" ;; check-description:) ;; # ignore check-note:) ;; # ignore @@ -301,6 +305,28 @@ do_test() return 3 fi fi + if [ "$check_assert" != "" ]; then + res=$(../sparse - 2>&1 >/dev/null <<- EOF + _Static_assert($check_assert, "$check_assert"); + EOF + ) + if [ "$res" != "" ]; then + disable "$test_name" "$file" + return 3 + fi + fi + if [ "$check_cpp_if" != "" ]; then + res=$(../sparse -E - 2>/dev/null <<- EOF + #if !($check_cpp_if) + fail + #endif + EOF + ) + if [ "$res" != "" ]; then + disable "$test_name" "$file" + return 3 + fi + fi if [ -z "$vquiet" ]; then echo " TEST $test_name ($file)" diff --git a/validation/typedef-redef-c89.c b/validation/typedef-redef-c89.c new file mode 100644 index 00000000..6d4dc28c --- /dev/null +++ b/validation/typedef-redef-c89.c @@ -0,0 +1,13 @@ +typedef int int_t; +typedef int int_t; + +/* + * check-name: typedef-redef-c89 + * check-command: sparse -std=c89 --pedantic $file + * check-known-to-fail + * + * check-error-start +typedef-redef-c89.c:2:13: warning: redefinition of typedef 'int_t' +typedef-redef-c89.c:1:13: info: originally defined here + * check-error-end + */ diff --git a/validation/typedef-redef.c b/validation/typedef-redef.c new file mode 100644 index 00000000..3a60a773 --- /dev/null +++ b/validation/typedef-redef.c @@ -0,0 +1,13 @@ +typedef int ok_t; +typedef int ok_t; + +typedef int ko_t; +typedef long ko_t; + +/* + * check-name: typedef-redef + * + * check-error-start +typedef-redef.c:5:14: error: symbol 'ko_t' redeclared with different type (originally declared at typedef-redef.c:4) - different type sizes + * check-error-end + */ diff --git a/validation/typediff-arraysize.c b/validation/typediff-arraysize.c new file mode 100644 index 00000000..dd7a2ca5 --- /dev/null +++ b/validation/typediff-arraysize.c @@ -0,0 +1,12 @@ +extern int ok0[]; int ok0[1]; // OK +extern int ok1[1]; int ok1[]; // OK but size should be 1 +extern int ko1[1]; int ko1[2]; // KO + +/* + * check-name: typediff-arraysize + * check-known-to-fail + * + * check-error-start +typediff-arraysize.c:3:29: error: symbol 'ko1' redeclared with different type (originally declared at typediff-arraysize.c:3) - different array sizes + * check-error-end + */ diff --git a/validation/typediff-enum.c b/validation/typediff-enum.c new file mode 100644 index 00000000..c5f2dc0a --- /dev/null +++ b/validation/typediff-enum.c @@ -0,0 +1,34 @@ +enum num { ZERO, ONE, MANY, }; +typedef enum num num; + +extern int v; +num v = 0; + +extern num w; +int w = 0; + +int foo(void); +num foo(void) { return ZERO; } + +num bar(void); +int bar(void) { return ZERO; } + +void baz(int a); +void baz(num a) { } + +void qux(num a); +void qux(int a) { } + +/* + * check-name: typediff-enum + * check-known-to-fail + * + * check-error-start +typediff-enum.c:5:5: error: symbol 'v' redeclared with different type (originally declared at typediff-enum.c:4) - different types +typediff-enum.c:8:5: error: symbol 'w' redeclared with different type (originally declared at typediff-enum.c:7) - different types +typediff-enum.c:11:5: error: symbol 'foo' redeclared with different type (originally declared at typediff-enum.c:10) - different types +typediff-enum.c:14:5: error: symbol 'bar' redeclared with different type (originally declared at typediff-enum.c:13) - different types +typediff-enum.c:17:6: error: symbol 'baz' redeclared with different type (originally declared at typediff-enum.c:16) - incompatible argument 1 (different types) +typediff-enum.c:20:6: error: symbol 'qux' redeclared with different type (originally declared at typediff-enum.c:19) - incompatible argument 1 (different types) + * check-error-end + */ |
