diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /support/valdiag | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'support/valdiag')
| -rw-r--r-- | support/valdiag/Makefile | 54 | ||||
| -rw-r--r-- | support/valdiag/Makefile.in | 54 | ||||
| -rw-r--r-- | support/valdiag/tests/bug-2773.c | 17 | ||||
| -rw-r--r-- | support/valdiag/tests/bug-895992.c | 34 | ||||
| -rw-r--r-- | support/valdiag/tests/bug-971834.c | 49 | ||||
| -rw-r--r-- | support/valdiag/tests/cflow.c | 26 | ||||
| -rw-r--r-- | support/valdiag/tests/const.c | 21 | ||||
| -rw-r--r-- | support/valdiag/tests/constantRange.c | 267 | ||||
| -rw-r--r-- | support/valdiag/tests/declafterstmt.c | 45 | ||||
| -rw-r--r-- | support/valdiag/tests/enum.c | 89 | ||||
| -rw-r--r-- | support/valdiag/tests/funcdec.c | 48 | ||||
| -rw-r--r-- | support/valdiag/tests/overflow.c | 61 | ||||
| -rw-r--r-- | support/valdiag/tests/pointers.c | 21 | ||||
| -rw-r--r-- | support/valdiag/tests/primtypes.c | 100 | ||||
| -rw-r--r-- | support/valdiag/tests/restrict.c | 63 | ||||
| -rw-r--r-- | support/valdiag/tests/static_assert.c | 19 | ||||
| -rw-r--r-- | support/valdiag/tests/struct.c | 115 | ||||
| -rw-r--r-- | support/valdiag/tests/structflexiblearray.c | 24 | ||||
| -rw-r--r-- | support/valdiag/tests/switch.c | 158 | ||||
| -rw-r--r-- | support/valdiag/tests/tentdecl.c | 127 | ||||
| -rw-r--r-- | support/valdiag/tests/typedef.c | 45 | ||||
| -rw-r--r-- | support/valdiag/valdiag.py | 397 |
22 files changed, 1834 insertions, 0 deletions
diff --git a/support/valdiag/Makefile b/support/valdiag/Makefile new file mode 100644 index 0000000..af97388 --- /dev/null +++ b/support/valdiag/Makefile @@ -0,0 +1,54 @@ +.SILENT: + +PYTHON = python3.6 + +srcdir = . +top_srcdir = ../.. +top_builddir = ../.. + +TESTS_DIR = $(srcdir)/tests +RESULTS_DIR = results +PORTS_DIR = $(srcdir)/ports +BUILD_DIR = gen +ALL_PORTS = mcs51 mcs51-large mcs51-stack-auto ds390 z80 z180 r2k gbz80 tlcs90 hc08 s08 stm8 pdk14 + +ALL_TESTS = $(shell find $(TESTS_DIR) -name "*.c") + +PORT_RESULTS_DIR = $(RESULTS_DIR)/$(PORT) +PORT_RESULTS = $(ALL_TESTS:$(TESTS_DIR)/%.c=$(PORT_RESULTS_DIR)/%.out) +PORT_BUILD_DIR = $(BUILD_DIR)/$(PORT) + +all: test-ports + +test-ports: + for i in $(ALL_PORTS); do $(MAKE) test-port PORT=$$i; done + +test-mcs51: + $(MAKE) test-port PORT=mcs51 + +test-port: port-results + +clean: clean-gen + rm -rf $(RESULTS_DIR) *.pyc + rm -rf $(BUILD_DIR) + +distclean: clean + rm -r Makefile + +clean-gen: + for i in $(ALL_PORTS); do $(MAKE) clean-port PORT=$$i; done + +clean-port: + rm -rf $(PORT_BUILD_DIR) + +$(PORT_RESULTS_DIR)/%.out: $(TESTS_DIR)/%.c + $(PYTHON) $(srcdir)/valdiag.py $(PORT) $< $(PORT_BUILD_DIR)/$* $(srcdir)/../../device/include > $@ + grep FAIL $@ ; true + cat $@ | $(PYTHON) $(srcdir)/../regression/compact-results.py + +port-results: port-dirs $(PORT_RESULTS) + cat $(PORT_RESULTS) | $(PYTHON) $(srcdir)/../regression/collate-results.py $(PORT) + +port-dirs: + mkdir -p $(PORT_RESULTS_DIR) + mkdir -p $(PORT_BUILD_DIR) diff --git a/support/valdiag/Makefile.in b/support/valdiag/Makefile.in new file mode 100644 index 0000000..732de5f --- /dev/null +++ b/support/valdiag/Makefile.in @@ -0,0 +1,54 @@ +.SILENT: + +PYTHON = @PYTHON@ +VPATH = @srcdir@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ + +TESTS_DIR = $(srcdir)/tests +RESULTS_DIR = results +PORTS_DIR = $(srcdir)/ports +BUILD_DIR = gen +ALL_PORTS = mcs51 mcs51-large mcs51-stack-auto ds390 z80 z180 r2k gbz80 tlcs90 hc08 s08 stm8 pdk14 + +ALL_TESTS = $(shell find $(TESTS_DIR) -name "*.c") + +PORT_RESULTS_DIR = $(RESULTS_DIR)/$(PORT) +PORT_RESULTS = $(ALL_TESTS:$(TESTS_DIR)/%.c=$(PORT_RESULTS_DIR)/%.out) +PORT_BUILD_DIR = $(BUILD_DIR)/$(PORT) + +all: test-ports + +test-ports: + for i in $(ALL_PORTS); do $(MAKE) test-port PORT=$$i; done + +test-mcs51: + $(MAKE) test-port PORT=mcs51 + +test-port: port-results + +clean: clean-gen + rm -rf $(RESULTS_DIR) *.pyc + rm -rf $(BUILD_DIR) + +distclean: clean + rm -r Makefile + +clean-gen: + for i in $(ALL_PORTS); do $(MAKE) clean-port PORT=$$i; done + +clean-port: + rm -rf $(PORT_BUILD_DIR) + +$(PORT_RESULTS_DIR)/%.out: $(TESTS_DIR)/%.c + $(PYTHON) $(srcdir)/valdiag.py $(PORT) $< $(PORT_BUILD_DIR)/$* $(srcdir)/../../device/include > $@ + grep FAIL $@ ; true + cat $@ | $(PYTHON) $(srcdir)/../regression/compact-results.py + +port-results: port-dirs $(PORT_RESULTS) + cat $(PORT_RESULTS) | $(PYTHON) $(srcdir)/../regression/collate-results.py $(PORT) + +port-dirs: + mkdir -p $(PORT_RESULTS_DIR) + mkdir -p $(PORT_BUILD_DIR) diff --git a/support/valdiag/tests/bug-2773.c b/support/valdiag/tests/bug-2773.c new file mode 100644 index 0000000..7ccf7ab --- /dev/null +++ b/support/valdiag/tests/bug-2773.c @@ -0,0 +1,17 @@ +/* bug-2773.c + + Missing diagnostic on duplicate paramter name + */ + +#ifdef TEST1 +extern void *h2 (int g2, int g2); /* ERROR */ +#endif + +#ifdef TEST2 +int i; + +extern void *h (int g, int g) { /* ERROR */ + i = g; +} +#endif + diff --git a/support/valdiag/tests/bug-895992.c b/support/valdiag/tests/bug-895992.c new file mode 100644 index 0000000..24bf327 --- /dev/null +++ b/support/valdiag/tests/bug-895992.c @@ -0,0 +1,34 @@ + +/* bug-895992.c + + Life Range problem with + - uninitialized variable + - loop + - conditional block + */ + +#ifdef TEST1 +char p0; + +void wait (void); + +void foo(void) +{ + unsigned char number; + unsigned char start = 1; + unsigned char i; + + do + { + for (i = 1; i > 0 ; i--) + wait(); + if (start) + { + number = p0; + start = 0; + } + number--; /* WARNING(SDCC) */ + } + while (number != 0); +} +#endif diff --git a/support/valdiag/tests/bug-971834.c b/support/valdiag/tests/bug-971834.c new file mode 100644 index 0000000..27df123 --- /dev/null +++ b/support/valdiag/tests/bug-971834.c @@ -0,0 +1,49 @@ + +/* bug-971834.c + + Life Range problem with + - uninitialized variable + - loop + */ + +#ifdef TEST1 +unsigned char ttt = 2; + +short foo (void) +{ + unsigned short a; + a |= ttt; /* WARNING(SDCC || GCC) */ + return a; +} +#endif + + +#ifdef TEST2 +unsigned char ttt[] = {0xff, 1}; + +char foo (void) +{ + unsigned char a, i; + for (i = 0; i < sizeof(ttt); i++) + a |= ttt[i]; /* WARNING(SDCC) */ + return a; +} +#endif + +#ifdef TEST3 +unsigned char ttt[] = {0xff, 1}; +unsigned char b; + +char foo (void) +{ + unsigned char i, j; + unsigned char a; + for (j = 0; j < sizeof(ttt); j++) { + for (i = 0; i < sizeof(ttt); i++) { + a |= ttt[i]; /* WARNING(SDCC) */ + b = a; + } + } + return b; +} +#endif diff --git a/support/valdiag/tests/cflow.c b/support/valdiag/tests/cflow.c new file mode 100644 index 0000000..b584550 --- /dev/null +++ b/support/valdiag/tests/cflow.c @@ -0,0 +1,26 @@ + +int x; + +#ifdef TEST0 +void foo(void) +{ + while (1) ; +} +#endif + +#ifdef TEST1 +void foo(void) +{ + while (1) ; + x++; /* WARNING(SDCC) */ +} +#endif + +#ifdef TEST2 +void foo(void) +{ + int y=1; + while (y) ; /* WARNING(SDCC) */ + x++; /* WARNING(SDCC) */ +} +#endif diff --git a/support/valdiag/tests/const.c b/support/valdiag/tests/const.c new file mode 100644 index 0000000..5082081 --- /dev/null +++ b/support/valdiag/tests/const.c @@ -0,0 +1,21 @@ + +char a; +const char ca=2; +const char *pca; +char * const cpa=&a; + +void test(void) +{ + a = 1; +#ifdef TEST1 + ca = a; /* ERROR */ +#endif +#ifdef TEST2 + pca = &a; + *pca = 2; /* ERROR */ +#endif +#ifdef TEST3 + *cpa = 3; + cpa = &ca; /* ERROR */ +#endif +} diff --git a/support/valdiag/tests/constantRange.c b/support/valdiag/tests/constantRange.c new file mode 100644 index 0000000..8e4c793 --- /dev/null +++ b/support/valdiag/tests/constantRange.c @@ -0,0 +1,267 @@ +#include <stdint.h> + +volatile int8_t c; + +/* sorry about the uggly source, + but this way it can be the same as in the regression tests */ +#define ASSERT(x) c = (x) + + int8_t s8; +uint8_t u8; + + int16_t s16; +uint16_t u16; + + int32_t s32; +uint32_t u32; + +#ifdef TEST1 +void foo(void) +{ + ASSERT (! (INT8_MIN - 1 == s8)); /* WARNING */ + ASSERT (! (INT8_MAX + 1 == s8)); /* WARNING */ + ASSERT ( (INT8_MIN - 1 != s8)); /* WARNING */ + ASSERT ( (INT8_MAX + 1 != s8)); /* WARNING */ + ASSERT ( (INT8_MIN - 1 < s8)); /* WARNING */ + ASSERT (! (INT8_MAX < s8)); /* WARNING */ + ASSERT ( (INT8_MIN <= s8)); /* WARNING */ + ASSERT (! (INT8_MAX + 1 <= s8)); /* WARNING */ + ASSERT (! (INT8_MIN > s8)); /* WARNING */ + ASSERT ( (INT8_MAX + 1 > s8)); /* WARNING */ + ASSERT (! (INT8_MIN - 1 >= s8)); /* WARNING */ + ASSERT ( (INT8_MAX >= s8)); /* WARNING */ + + ASSERT (! ( 0 - 1 == u8)); /* WARNING */ + ASSERT (! (UINT8_MAX + 1 == u8)); /* WARNING */ + ASSERT ( ( 0 - 1 != u8)); /* WARNING */ + ASSERT ( (UINT8_MAX + 1 != u8)); /* WARNING */ + ASSERT ( ( 0 - 1 < u8)); /* WARNING */ + ASSERT (! (UINT8_MAX < u8)); /* WARNING */ + ASSERT ( ( 0 <= u8)); /* WARNING */ + ASSERT (! (UINT8_MAX + 1 <= u8)); /* WARNING */ + ASSERT (! ( 0 > u8)); /* WARNING */ + ASSERT ( (UINT8_MAX + 1 > u8)); /* WARNING */ + ASSERT (! ( 0 - 1 >= u8)); /* WARNING */ + ASSERT ( (UINT8_MAX >= u8)); /* WARNING */ + + /* force extension to long to avoid int (16 bit) overflow */ + ASSERT (! (INT16_MIN - 1L == s16)); /* WARNING */ + ASSERT (! (INT16_MAX + 1L == s16)); /* WARNING */ + ASSERT ( (INT16_MIN - 1L != s16)); /* WARNING */ + ASSERT ( (INT16_MAX + 1L != s16)); /* WARNING */ + ASSERT ( (INT16_MIN - 1L < s16)); /* WARNING */ + ASSERT (! (INT16_MAX < s16)); /* WARNING */ + ASSERT ( (INT16_MIN <= s16)); /* WARNING */ + ASSERT (! (INT16_MAX + 1L <= s16)); /* WARNING */ + ASSERT (! (INT16_MIN > s16)); /* WARNING */ + ASSERT ( (INT16_MAX + 1L > s16)); /* WARNING */ + ASSERT (! (INT16_MIN - 1L >= s16)); /* WARNING */ + ASSERT ( (INT16_MAX >= s16)); /* WARNING */ + + ASSERT (! ( 0 - 1L == u16)); /* WARNING */ + ASSERT (! (UINT16_MAX + 1L == u16)); /* WARNING */ + ASSERT ( ( 0 - 1L != u16)); /* WARNING */ + ASSERT ( (UINT16_MAX + 1L != u16)); /* WARNING */ + ASSERT ( ( 0 - 1L < u16)); /* WARNING */ + ASSERT (! (UINT16_MAX < u16)); /* WARNING */ + ASSERT ( ( 0 <= u16)); /* WARNING */ + ASSERT (! (UINT16_MAX + 1L <= u16)); /* WARNING */ + ASSERT (! ( 0 > u16)); /* WARNING */ + ASSERT ( (UINT16_MAX + 1L > u16)); /* WARNING */ + ASSERT (! ( 0 - 1L >= u16)); /* WARNING */ + ASSERT ( (UINT16_MAX >= u16)); /* WARNING */ + + /* sdcc can't hold a number (INT32_MIN - 1) or (INT32_MAX + 1), + there's no 'double' or 'long long' */ +/* ASSERT (! (INT32_MIN - 1 == s32)); */ +/* ASSERT (! (INT32_MAX + 1 == s32)); */ +/* ASSERT ( (INT32_MIN - 1 != s32)); */ +/* ASSERT ( (INT32_MAX + 1 != s32)); */ +/* ASSERT ( (INT32_MIN - 1 < s32)); */ + ASSERT (! (INT32_MAX < s32)); /* WARNING(SDCC) */ + ASSERT ( (INT32_MIN <= s32)); /* WARNING(SDCC) */ +/* ASSERT (! (INT32_MAX + 1 <= s32)); */ + ASSERT (! (INT32_MIN > s32)); /* WARNING(SDCC) */ +/* ASSERT ( (INT32_MAX + 1 > s32)); */ +/* ASSERT (! (INT32_MIN - 1 >= s32)); */ + ASSERT ( (INT32_MAX >= s32)); /* WARNING(SDCC) */ + + /* (0 - 1) wraps around to UINT32_MAX -> untestable */ +/* ASSERT (! ( 0 - 1 == u32)); */ +/* ASSERT (! (UINT32_MAX + 1 == u32)); */ +/* ASSERT ( ( 0 - 1 != u32)); */ +/* ASSERT ( (UINT32_MAX + 1 != u32)); */ +/* ASSERT ( ( 0 - 1 < u32)); */ + ASSERT (! (UINT32_MAX < u32)); /* WARNING(SDCC) */ + ASSERT ( ( 0 <= u32)); /* WARNING(SDCC) */ +/* ASSERT (! (UINT32_MAX + 1 <= u32)); */ + ASSERT (! ( 0 > u32)); /* WARNING(SDCC) */ +/* ASSERT ( (UINT32_MAX + 1 > u32)); */ +/* ASSERT (! ( 0 - 1 >= u32)); */ + ASSERT ( (UINT32_MAX >= u32)); /* WARNING(SDCC) */ +} +#endif + +#ifdef TEST2 +void foo(void) +{ + s8 = -129; /* WARNING */ + s8 = INT8_MIN; + s8 = UINT8_MAX; /* WARNING */ + s8 = 256; /* WARNING */ + + s8 = -129; /* WARNING */ + u8 = INT8_MIN; /* WARNING */ + u8 = UINT8_MAX; + u8 = 256; /* WARNING */ + + s16 = -32769L; /* WARNING */ + s16 = INT16_MIN; + s16 = UINT16_MAX; /* WARNING */ + s16 = 65536L; /* WARNING */ + + s16 = -32769L; /* WARNING */ + u16 = INT16_MIN; /* WARNING */ + u16 = UINT16_MAX; + u16 = 65536L; /* WARNING */ + + /* sdcc can't hold a number (INT32_MIN - 1) or (INT32_MAX + 1), + there's no 'double' or 'long long' */ + s32 = INT32_MIN; + s32 = UINT32_MAX; /* WARNING */ + + u32 = INT32_MIN; /* WARNING */ + u32 = UINT32_MAX; +} +#endif + +/* This test has been disabled. I don't think that signed/unsigned bool */ +/* is a valid type. -- EEP */ +#ifdef TEST3_DISABLED +#include <stdbool.h> + +void foo(void) +{ +#if defined(PORT_HOST) + volatile bool sb, ub; +#else + volatile signed bool sb; + volatile unsigned bool ub; +#endif + + sb = -2; + sb = -1; + sb = 0; + sb = 1; + + ub = -1; + ub = 0; + ub = 1; + ub = 2; + + ASSERT (! (-2 == sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + ASSERT ( (-1 == sb)); + ASSERT ( ( 0 == sb)); + ASSERT (! ( 1 == sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT ( (-2 != sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + ASSERT ( (-1 != sb)); + ASSERT ( ( 0 != sb)); + ASSERT ( ( 1 != sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT ( (-2 < sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + ASSERT ( (-1 < sb)); + ASSERT (! ( 0 < sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT ( (-1 <= sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + ASSERT ( ( 0 <= sb)); + ASSERT (! ( 1 <= sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT (! (-1 > sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + ASSERT ( ( 0 > sb)); + ASSERT ( ( 1 > sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT (! (-2 >= sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + ASSERT ( (-1 >= sb)); + ASSERT ( ( 0 >= sb)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + + ASSERT (! (-1 == ub)); /* WARNING(SDCC) */ + ASSERT ( ( 0 == ub)); + ASSERT ( ( 1 == ub)); + ASSERT (! ( 2 == ub)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT ( (-1 != ub)); /* WARNING(SDCC) */ + ASSERT ( ( 0 != ub)); + ASSERT ( ( 1 != ub)); + ASSERT ( ( 2 != ub)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT ( (-1 < ub)); /* WARNING(SDCC) */ + ASSERT ( ( 0 < ub)); + ASSERT (! ( 1 < ub)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT ( ( 0 <= ub)); /* WARNING(SDCC) */ + ASSERT ( ( 1 <= ub)); + ASSERT (! ( 2 <= ub)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT (! ( 0 > ub)); /* WARNING(SDCC) */ + ASSERT ( ( 1 > ub)); + ASSERT ( ( 2 > ub)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ + + ASSERT (! (-1 >= ub)); /* WARNING(SDCC) */ + ASSERT ( ( 0 >= ub)); + ASSERT ( ( 1 >= ub)); /* WARNING(SDCC_mcs51|SDCC_ds390) */ +} +#endif + +#ifdef TEST4 +void foo(void) +{ + volatile struct { + signed sb1:1; + signed sb3:3; + unsigned ub1:1; + unsigned ub3:3; + } str; + + str.sb1 = -2; /* WARNING */ + str.sb1 = -1; + str.sb1 = 1; /* WARNING */ + str.sb1 = 2; /* WARNING */ + + str.ub1 = -2; /* WARNING */ + str.ub1 = -1; /* WARNING */ + str.ub1 = 1; + str.ub1 = 2; /* WARNING */ + + str.sb3 = -5; /* WARNING */ + str.sb3 = -4; + str.sb3 = 7; /* WARNING */ + str.sb3 = 8; /* WARNING */ + + str.ub3 = -5; /* WARNING */ + str.ub3 = -4; /* WARNING */ + str.ub3 = 7; + str.ub3 = 8; /* WARNING */ + + ASSERT (! (-2 == str.sb1)); /* WARNING */ + ASSERT ( (-1 == str.sb1)); + ASSERT ( ( 0 == str.sb1)); + ASSERT (! ( 1 == str.sb1)); /* WARNING */ + + ASSERT (! (-1 == str.ub1)); /* WARNING(SDCC) */ + ASSERT ( ( 0 == str.ub1)); + ASSERT ( ( 1 == str.ub1)); + ASSERT (! ( 2 == str.ub1)); /* WARNING(SDCC) */ + + ASSERT (! (-5 == str.sb3)); /* WARNING */ + ASSERT ( (-4 == str.sb3)); + ASSERT ( ( 3 == str.sb3)); + ASSERT (! ( 4 == str.sb3)); /* WARNING */ + + ASSERT (! (-1 == str.ub3)); /* WARNING(SDCC) */ + ASSERT ( ( 0 == str.ub3)); + ASSERT ( ( 7 == str.ub3)); + ASSERT (! ( 8 == str.ub3)); /* WARNING(SDCC) */ +} +#endif diff --git a/support/valdiag/tests/declafterstmt.c b/support/valdiag/tests/declafterstmt.c new file mode 100644 index 0000000..51ce7ca --- /dev/null +++ b/support/valdiag/tests/declafterstmt.c @@ -0,0 +1,45 @@ +/* we are testing a C99 feature */ +#pragma std_c99 + +/* we do not care about unreferenced variables */ +#pragma disable_warning 85 + +#ifdef TEST1 +#pragma std_c89 +void test(void) +{ + int a = 0; + a++; + int b; +} /* ERROR */ /* declaration after statement within this block */ +#endif + +#ifdef TEST2 +void test(void) +{ + int a = 0; + a++; + int b; +} +#endif + +#ifdef TEST3 +void test(void) +{ + int a = 0; /* ERROR */ /* previously defined here */ + a++; + int a; /* ERROR */ /* duplicate symbol */ +} +#endif + +#ifdef TEST4 +void test(void) +{ + int a = 0; + a++; + int b; + { + int a; + } +} +#endif diff --git a/support/valdiag/tests/enum.c b/support/valdiag/tests/enum.c new file mode 100644 index 0000000..ac50ca1 --- /dev/null +++ b/support/valdiag/tests/enum.c @@ -0,0 +1,89 @@ + +#ifdef TEST1 +enum tag +{ + first, + second, + third +}; +#endif + +#ifdef TEST2 +enum tag +{ + first, /* IGNORE */ + second, + third, + first, /* ERROR */ + fourth +}; +#endif + + +#ifdef TEST3 +enum +{ + first, /* IGNORE */ + second, + third, + first, /* ERROR */ + fourth +}; +#endif + + +#ifdef TEST4 +enum +{ + first=1, + second, + third, +}; +#endif + + +#ifdef TEST5 +enum +{ + first=1.1, /* ERROR */ + second, + third, +}; +#endif + +#ifdef TEST6 +int second; /* IGNORE */ + +enum tag +{ + first, + second, /* ERROR */ + third +}; +#endif + +#ifdef TEST7 +enum tag /* IGNORE */ +{ + first, + second, + third +}; + +enum tag { /* ERROR */ + fourth, + fifth, + sixth +}; +#endif + +#ifdef TEST8 +enum tag x; /* IGNORE(GCC) */ + +enum tag +{ + first, + second, + third +}; +#endif diff --git a/support/valdiag/tests/funcdec.c b/support/valdiag/tests/funcdec.c new file mode 100644 index 0000000..c2e10bb --- /dev/null +++ b/support/valdiag/tests/funcdec.c @@ -0,0 +1,48 @@ + +#ifdef TEST1 +void foo(void); /* IGNORE */ +int foo(void) { } /* ERROR */ +#endif + +#ifdef TEST2 +void foo(void); /* IGNORE */ +void foo(int a) {a; } /* ERROR */ +#endif + + +#ifdef TEST3 +void foo(int); /* IGNORE */ +void foo(int a, int b) {a;b; } /* ERROR */ +#endif + +#ifdef TEST4 +void foo(int, int); /* IGNORE */ +void foo(int a) {a; } /* ERROR */ +#endif + +#if defined(__SDCC) && defined(__has_reentrant) +#define REENTRANT __reentrant +#define HAS_REENTRANT 1 +#else +#define REENTRANT +#define HAS_REENTRANT 0 +#endif + +#ifdef TEST5 +void foo(int, int) REENTRANT; /* IGNORE */ +#if HAS_REENTRANT +void foo(int a, int b) {a; b;} /* ERROR(SDCC && __has_reentrant && !SDCC_STACK_AUTO) */ +#endif +#endif + +#ifdef TEST6 +void foo(int a=1) /* ERROR */ +{ +} +#endif + +#ifdef TEST7 +void foo(static int a) /* ERROR */ +{ +} +#endif diff --git a/support/valdiag/tests/overflow.c b/support/valdiag/tests/overflow.c new file mode 100644 index 0000000..39ecbd3 --- /dev/null +++ b/support/valdiag/tests/overflow.c @@ -0,0 +1,61 @@ +volatile char c; +volatile unsigned char uc; +volatile int i; +volatile unsigned u; +volatile long l; +volatile unsigned long ul; + +#ifdef TEST0 +void foo(void) +{ + i = 10000 * 10000; /* WARNING(SDCC) */ + i = 0x4000 * 0x4000; /* WARNING(SDCC) */ +} +#endif + +#ifdef TEST1 +void foo(void) +{ + uc = 1 << 7; /* IGNORE(SDCC) */ // Gives a false warning (bug #2733) + + i = c << 10; + i = 1 << 10; + i = c << 16; /* WARNING(SDCC) */ + i = 1 << 16; /* WARNING(SDCC) */ + i = uc << 16; /* WARNING(SDCC) */ + + l = l << 31; + l = l << 32; /* WARNING(SDCC) */ /* IGNORE(GCC) */ + l = ul << 32; /* WARNING(SDCC) */ /* IGNORE(GCC) */ +} +#endif + + +#ifdef TEST2 +void foo(void) +{ + i = 1 >> 40; /* IGNORE(SDCC) */ /* WARNING(GCC) */ // Warning missing (bug #2734) + + i = uc >> 7; + i = 1 >> 7; + i = uc >> 8; /* WARNING(SDCC) */ +#if 0 + i = 1 >> 8; /* WARN___(SDCC) */ +#endif + +#if 0 + i = i >> 40; /* WARN___(GCC) */ +#endif + + i = u >> 15; + i = u >> 16; /* WARNING(SDCC) */ + +#if 0 + i = l >> 40; /* WARN___(GCC) */ +#endif + + i = ul >> 31; + i = ul >> 32; /* WARNING(SDCC) */ /* IGNORE(GCC) */ +} +#endif + diff --git a/support/valdiag/tests/pointers.c b/support/valdiag/tests/pointers.c new file mode 100644 index 0000000..16d71b1 --- /dev/null +++ b/support/valdiag/tests/pointers.c @@ -0,0 +1,21 @@ + +#ifdef TEST0 + +typedef void (*fptr1_t)(void); +typedef void (*fptr2_t)(int); + +fptr1_t fptr1; +fptr2_t fptr2; + +void *vp = 0; + +void testPtr(void) +{ + fptr1 = vp; /* WARNING */ + fptr2 = fptr1; /* IGNORE(GCC) */ + vp = fptr1; /* WARNING */ + fptr1 = (void *)0; +} + +#endif + diff --git a/support/valdiag/tests/primtypes.c b/support/valdiag/tests/primtypes.c new file mode 100644 index 0000000..c6dac5c --- /dev/null +++ b/support/valdiag/tests/primtypes.c @@ -0,0 +1,100 @@ +#ifdef TESTchar +char a; +#endif + +#ifdef TESTint +int a; +#endif + +#ifdef TESTlong +long a; +#endif + +#ifdef TESTshort +short a; +#endif + +#ifdef TESTintlong +long int a; +#endif + +#ifdef TESTintshort +short int a; +#endif + +#ifdef TESTsigned +signed a; +#endif + +#ifdef TESTunsigned +unsigned a; +#endif + +#ifdef TESTintsigned +signed int a; +#endif + +#ifdef TESTintunsigned +unsigned int a; +#endif + +#ifdef TESTfloat +float a; +#endif + +#ifdef TESTfloatsigned +signed float a; /* ERROR */ +#endif + +#ifdef TESTfloatunsigned +unsigned float a; /* ERROR */ +#endif + +#ifdef TESTfloatshort +short float a; /* ERROR */ +#endif + +#ifdef TESTfloatlong +long float a; /* ERROR */ +#endif + +#ifdef TESTdouble +double a; /* WARNING(SDCC) */ +#endif + +#ifdef TESTdoubleshort +short double a; /* ERROR */ +#endif + +#ifdef TESTdoublelong +long double a; /* WARNING(SDCC) */ +#endif + +#ifdef TESTdoublesigned +signed double a; /* ERROR */ +#endif + +#ifdef TESTdoubleunsigned +unsigned double a; /* ERROR */ +#endif + +#ifdef TESTbit +__bit a; /* ERROR(!__has_bit) */ +#endif + +#ifdef TESTsu1 +signed unsigned int a; /* ERROR */ +#endif + +#ifdef TESTsu2 +unsigned signed int a; /* ERROR */ +#endif + +#ifdef TESTsu3 +unsigned signed a; /* ERROR */ +#endif + +#ifdef TESTsu4 +signed unsigned a; /* ERROR */ +#endif + diff --git a/support/valdiag/tests/restrict.c b/support/valdiag/tests/restrict.c new file mode 100644 index 0000000..3dbcee3 --- /dev/null +++ b/support/valdiag/tests/restrict.c @@ -0,0 +1,63 @@ + +/* The restrict keyword can only qualify pointers to objects */ + +#ifdef TEST1_C99 +restrict a; /* ERROR */ +#endif + +#ifdef TEST2_C99 +restrict int a; /* ERROR */ +#endif + +#ifdef TEST3_C99 +restrict int a[10]; /* ERROR */ +#endif + +#ifdef TEST4_C99 +restrict int * a; /* ERROR */ +#endif + +#ifdef TEST5_C99 +restrict struct + { + int a; + int b; + } x; /* ERROR */ +#endif + +#ifdef TEST6_C99 +restrict int func(void) { /* ERROR */ + return 0; +} +#endif + +#ifdef TEST7_C99 +void func(restrict int x) { /* ERROR */ + x; /* IGNORE */ +} +#endif + +#ifdef TEST8_C99 +void func(void (*restrict p)(void)) { /* ERROR */ + p(); /* IGNORE */ +} +#endif + + +#ifdef TEST_GOOD1_C99 +int * restrict a; +#endif + +#ifdef TEST_GOOD2_C99 +int * func(int * restrict x) +{ + return x; +} +#endif + +#ifdef TEST_GOOD3_C99 +void func(int * restrict x) +{ + x; /* IGNORE */ +} +#endif diff --git a/support/valdiag/tests/static_assert.c b/support/valdiag/tests/static_assert.c new file mode 100644 index 0000000..c4a6254 --- /dev/null +++ b/support/valdiag/tests/static_assert.c @@ -0,0 +1,19 @@ +#pragma std_c11 + +#include <assert.h> + +/* C11 static_assert */ +#ifdef TEST1 +#pragma std_c11 +static_assert (1, "text"); +static_assert (0, "test"); /* WARNING */ +static_assert (1); /* ERROR */ +#endif + +/* C2X static_assert */ +#ifdef TEST2 +#pragma std_c2x +static_assert (1); +static_assert (0); /* WARNING */ +#endif + diff --git a/support/valdiag/tests/struct.c b/support/valdiag/tests/struct.c new file mode 100644 index 0000000..c7f4938 --- /dev/null +++ b/support/valdiag/tests/struct.c @@ -0,0 +1,115 @@ + +#ifdef TEST1 +struct tag { + int good1; + register int bad; /* ERROR */ + int good2; +} badstruct; /* IGNORE */ +#endif + +#ifdef TEST2 +struct tag { + int good1; + int bad; /* IGNORE */ + int bad; /* ERROR */ + int good2; +} badstruct; +#endif + +#ifdef TEST3a +struct tag { + int good1; + int bad:255; /* ERROR */ + int good2; +} badstruct; +#endif + +#ifdef TEST3b +struct tag { + int good1; + float badtype1 : 5; /* ERROR */ + int good2; + _Bool badwidth2 : 2; /* ERROR */ + int good3; + int badwidth2 : 17; /* ERROR */ + int good4; +} badstruct; +#endif + +#ifdef TEST4 +struct tag { + int good1; + int good2; +} goodstruct1; + +struct tag goodstruct2; +#endif + +#ifdef TEST5a +struct tag { + int good1; + int good2; +} goodstruct1; + +union tag badunion; /* ERROR */ +#endif + +#ifdef TEST5b +union tag { + int good1; + int good2; +} goodunion1; + +struct tag badstruct; /* ERROR */ +#endif + + +#ifdef TEST6 +struct linklist { + struct linklist *prev; + struct linklist *next; + int x; +} ll; +#endif + +#ifdef TEST7a +union tag { + struct tag *next; /* ERROR */ + int x; +} ll; +#endif + +#ifdef TEST7b +struct tag { + union tag *next; /* ERROR */ + int x; +} ll; +#endif + +#ifdef TEST8a +struct tag { + int a; /* IGNORE */ + struct { + int a; /* ERROR(SDCC) */ /* IGNORE(GCC) */ + int b; + }; +} ll; +#endif + +#ifdef TEST8b +struct tag { + int a; + struct { + int b; + int c; + }; +} ll; + +void test(void) +{ + ll.a = 1; + ll.b = 2; + ll.c = 3; +} + +#endif diff --git a/support/valdiag/tests/structflexiblearray.c b/support/valdiag/tests/structflexiblearray.c new file mode 100644 index 0000000..9f1c8e3 --- /dev/null +++ b/support/valdiag/tests/structflexiblearray.c @@ -0,0 +1,24 @@ + +#ifdef TEST1 +struct tag { + int good1; + int flex[]; /* ERROR */ + int good2; +} badstruct; +#endif + +#ifdef TEST2 +struct tag { + int flex[]; /* ERROR */ +} badstruct; +#endif + +#ifdef TEST3 +struct tag { + int good1; + struct tag2 { + int good2; + int flex[]; + } nestedstruct; /* ERROR(SDCC) */ +} badstruct; +#endif diff --git a/support/valdiag/tests/switch.c b/support/valdiag/tests/switch.c new file mode 100644 index 0000000..b9acd42 --- /dev/null +++ b/support/valdiag/tests/switch.c @@ -0,0 +1,158 @@ + +char x; + +/* Valid switch statement */ +#ifdef TEST1 +char foo(void) +{ + switch(x) + { + char y; + + case 0: + return 0; + case 1: + return 1; + default: + y = x+1; + return y; + } +} +#endif + +/* Error, duplicate cases */ +#ifdef TEST2 +char foo(void) +{ + switch(x) + { + char y; + + case 0: /* IGNORE */ + return 0; + case 1: + return 1; + case 0: /* ERROR */ + return 0; + default: + y = x; + return y; + } +} +#endif + +/* Error, more than one default */ +#ifdef TEST3 +char foo(void) +{ + switch(x) + { + char y; + + case 0: + return 0; + case 1: + return 1; + default: /* IGNORE */ + y = x; + return y; + default: /* ERROR */ + return 2; + } +} +#endif + +/* Warn about unreachable code */ +#ifdef TEST4 +char foo(void) +{ + switch(x) + { + char y; /* IGNORE */ + x++; /* WARNING(SDCC) */ + + case 0: + return 0; + case 1: + return 1; + default: + y = x; + return x; + } +} +#endif + +/* Warn about unreachable initializer */ +#ifdef TEST5 +char foo(void) +{ + switch(x) + { + char y=1; /* WARNING(SDCC) */ + + case 0: + return 0; + case 1: + return 1; + default: + return y; /* IGNORE */ + } +} +#endif + +/* Error, missing switch */ +#ifdef TEST6 +char foo(void) +{ + { + case 0: /* ERROR */ + return 0; + case 1: /* ERROR */ + return 1; + default: /* ERROR */ + return x; + } +} +#endif + +/* Error, switch condition must be integral */ +#ifdef TEST7 +char foo(void) +{ + float f; /* IGNORE */ + f=x; + switch(f) /* ERROR */ + { + char y; /* IGNORE */ + + case 0: + return 0; + case 1: + return 1; + default: + y = x; + return x; + } + return 0; +} +#endif + +/* Error, cases must be integral */ +#ifdef TEST8 +char foo(void) +{ + switch(x) + { + char y; /* IGNORE */ + + case 0.0: /* ERROR */ + return 0; + case 1: + return 1; + default: + y = x; + return x; + } +} +#endif + diff --git a/support/valdiag/tests/tentdecl.c b/support/valdiag/tests/tentdecl.c new file mode 100644 index 0000000..8b8e6b7 --- /dev/null +++ b/support/valdiag/tests/tentdecl.c @@ -0,0 +1,127 @@ + +#ifdef TEST0 +int a; +int a; +#endif + +#ifdef TEST1 +int a; /* IGNORE */ +char a; /* ERROR */ +#endif + +#ifdef TEST2 +int a; /* IGNORE */ +int *a; /* ERROR */ +#endif + +#ifdef TEST3 +int *a; /* IGNORE */ +int a[5]; /* ERROR */ +#endif + +/* array size must match */ + +#ifdef TEST4 +int a[4]; /* IGNORE */ +int a[5]; /* ERROR */ +#endif + +/* but it is legal to clarify */ +/* an incomplete type */ + +#ifdef TEST4b +int a[]; +int a[5]; +#endif + +/* type qualifier must match */ + +#ifdef TEST5 +int a; /* IGNORE */ +volatile int a; /* ERROR */ +#endif + +#ifdef TEST6 +int a; /* IGNORE */ +const int a; /* ERROR */ +#endif + +#ifdef TEST7 +int a=1; /* IGNORE */ +int a=2; /* ERROR */ +#endif + +#ifdef TEST7a +int a=1; +int a; +#endif + +#ifdef TEST8 +int a=1; /* IGNORE */ +int a=1; /* ERROR */ +#endif + +#if defined(__SDCC) +#define AT(x) __at x +#else +#define AT(x) +#endif + +#if defined(__has_xdata) +#define XDATA __xdata +#define DATA __data +#else +#define XDATA +#define DATA +#endif + +#ifdef TEST9 +#ifdef __SDCC +XDATA int a; /* IGNORE */ +DATA int a; /* IGNORE(SDCC && __has_xdata) */ // Should be error, see bug #2735. +#endif +#endif + +#ifdef TEST9b +#ifdef __SDCC +DATA int a; /* IGNORE */ +XDATA int a; /* ERROR(SDCC && __has_xdata) */ +#endif +#endif + +#ifdef TEST9c +#ifdef __SDCC +extern DATA int a; +DATA int a; +#endif +#endif + +#ifdef TEST9d +#ifdef __SDCC +extern XDATA int a; +XDATA int a; +#endif +#endif + +#ifdef TEST9e +#ifdef __SDCC +extern XDATA int a; /* IGNORE */ +DATA int a; /* ERROR(SDCC && __has_xdata) */ +#endif +#endif + +#ifdef TEST9f +#ifdef __SDCC +extern DATA int a; /* IGNORE */ +XDATA int a; /* ERROR(SDCC && __has_xdata) */ +#endif +#endif + +#ifdef TEST10 +#if defined(__SDCC) && defined(__has_xdata) +extern volatile XDATA AT(0) int a; /* IGNORE */ +volatile XDATA int a; /* ERROR(SDCC && __has_xdata) */ +#endif +#endif + +int validDeclaraction; /* to make sure this is never an empty source file */ diff --git a/support/valdiag/tests/typedef.c b/support/valdiag/tests/typedef.c new file mode 100644 index 0000000..a24cbcc --- /dev/null +++ b/support/valdiag/tests/typedef.c @@ -0,0 +1,45 @@ + +#ifdef TEST1 +typedef union { + long l; + float f; +} floatlong; + +char func(char floatlong) +{ + return floatlong; +} +#endif + +#ifdef TEST2 +typedef union { + long l; + float f; +} floatlong; + +long func(float x) +{ + typedef union { + float f2; + long l2; + char c[4]; + } floatlong; + floatlong fl; + + fl.f2=x; + return fl.l2; +} +#endif + +/* This is no longer an error in C11, so test with earlier standard. */ +/* Unfortunately, GCC seems to accept this regardless. */ +#ifdef TEST3_C99 +typedef int I; /* IGNORE */ +typedef int I; /* ERROR(SDCC) */ +#endif + +#ifdef TEST4 +typedef int I; /* IGNORE */ +typedef char I; /* ERROR */ +#endif + diff --git a/support/valdiag/valdiag.py b/support/valdiag/valdiag.py new file mode 100644 index 0000000..469b5c1 --- /dev/null +++ b/support/valdiag/valdiag.py @@ -0,0 +1,397 @@ +#!/usr/bin/env python +#--------------------------------------------------------------------------- +# valdiag.py - Validate diagnostic messages from SDCC/GCC +# Written By - Erik Petrich . epetrich@users.sourceforge.net (2003) +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# In other words, you are welcome to use, share and improve this program. +# You are forbidden to forbid anyone else to use, share and improve +# what you give them. Help stamp out software-hoarding! +#--------------------------------------------------------------------------- + +from __future__ import print_function + +import sys, string, os, re, subprocess +from subprocess import Popen, PIPE, STDOUT + +macrodefs = {} +extramacrodefs = {} + +gcc = { + "CC":"gcc", + "CCFLAGS":"-c -pedantic -Wall -DPORT_HOST=1", + "CCDEF":"-D", + "CCOUTPUT":"-o", + "C89":"-std=c89", + "C99":"-std=c99", + "defined": { + "__GNUC__":"1", + "GCC":"1" + }, + "ignoremsg": [ + ] +} + +sdcc = { + "CC":"../../bin/sdcc", + "CCFLAGS":"-c -m{port}", + "CCDEF":"-D", + "CCOUTPUT":"-o", + "CCINCLUDEDIR":"-I", + "C89":"--std-sdcc89", + "C99":"--std-sdcc99", + "defined": { + "SDCC":"1", + "SDCC_{port}":"1", + "__{port}":"1" + }, + "ignoremsg": [ + "code not generated.*due to previous errors", + "unreferenced function argument" + ] +} + +testmodes = { + "host":{ + "compiler":gcc, + "port":"host", + "defined": { + "PORT_HOST":"1" + } + }, + "mcs51":{ + "compiler":sdcc, + "port":"mcs51", + "extra-defines": { + "__has_bit":"1", + "__has_data":"1", + "__has_xdata":"1", + "__has_reentrant":"1" + } + }, + "mcs51-large":{ + "compiler":sdcc, + "port":"mcs51", + "flags":"--model-large", + "defined": { + "SDCC_MODEL_LARGE":"1" + }, + "extra-defines" : { + "__has_bit":"1", + "__has_data":"1", + "__has_xdata":"1", + "__has_reentrant":"1" + } + }, + "mcs51-stack-auto":{ + "compiler":sdcc, + "port":"mcs51", + "flags":"--stack-auto", + "defined": { + "SDCC_STACK_AUTO":"1" + }, + "extra-defines": { + "__has_bit":"1", + "__has_data":"1", + "__has_xdata":"1", + "__has_reentrant":"1" + } + }, + "ds390":{ + "compiler":sdcc, + "port":"ds390", + "extra-defines": { + "__has_bit":"1", + "__has_data":"1", + "__has_xdata":"1", + "__has_reentrant":"1" + } + }, + "z80":{ + "compiler":sdcc, + "port":"z80" + }, + "z180":{ + "compiler":sdcc, + "port":"z180" + }, + "r2k":{ + "compiler":sdcc, + "port":"r2k" + }, + "gbz80":{ + "compiler":sdcc, + "port":"gbz80" + }, + "tlcs90":{ + "compiler":sdcc, + "port":"tlcs90" + }, + "hc08":{ + "compiler":sdcc, + "port":"hc08", + "extra-defines": { + "__has_data":"1", + "__has_xdata":"1", + "__has_reentrant":"1" + } + }, + "s08":{ + "compiler":sdcc, + "port":"s08", + "extra-defines": { + "__has_data":"1", + "__has_xdata":"1", + "__has_reentrant":"1" + } + }, + "stm8":{ + "compiler":sdcc, + "port":"stm8" + }, + "pdk14":{ + "compiler":sdcc, + "port":"pdk14" + }, + "pic14":{ + "compiler":sdcc, + "port":"pic14" + }, + "pic16":{ + "compiler":sdcc, + "port":"pic16" + } +} + + +def evalQualifier(expr): + global macrodefs + tokens = re.split("([^0-9A-Za-z_])", expr) + for tokenindex in range(len(tokens)): + token = tokens[tokenindex] + if token in macrodefs: + tokens[tokenindex] = macrodefs[token] + elif token == "defined": + tokens[tokenindex] = "" + if tokens[tokenindex+2] in macrodefs: + tokens[tokenindex+2] = "1" + else: + tokens[tokenindex+2] = "0" + elif len(token)>0: + if token[0]=="_" or token[0] in string.ascii_letters: + tokens[tokenindex] = "0" + #expr = string.join(tokens,"") + expr = "".join(tokens) + expr = expr.replace("&&"," and "); + expr = expr.replace("||"," or "); + expr = expr.replace("!"," not "); + return eval(expr) + +def expandPyExpr(expr): + tokens = re.split("({|})", expr) + for tokenindex in range(1,len(tokens)): + if tokens[tokenindex-1]=="{": + tokens[tokenindex]=eval(tokens[tokenindex]) + tokens[tokenindex-1]="" + tokens[tokenindex+1]="" + expandedExpr = "".join(tokens) + return expandedExpr + +def addDefines(deflist, isExtra): + for define in list(deflist.keys()): + expandeddef = expandPyExpr(define) + macrodefs[expandeddef] = expandPyExpr(deflist[define]) + if isExtra: + extramacrodefs[expandeddef] = macrodefs[expandeddef] + +def parseInputfile(inputfilename): + inputfile = open(inputfilename, "r") + testcases = {} + testname = "" + linenumber = 1 + + # Find the test cases and tests in this file + for line in inputfile.readlines(): + + # See if a new testcase is being defined + p = line.find("TEST") + if p>=0: + testname = line[p:].split()[0] + if testname not in testcases: + testcases[testname] = {} + + # See if a new test is being defined + for testtype in ["ERROR", "WARNING", "IGNORE"]: + p = line.find(testtype); + if p>=0: + # Found a test definition + qualifier = line[p+len(testtype):].strip() + p = qualifier.find("*/") + if p>=0: + qualifier = qualifier[:p].strip() + if len(qualifier)==0: + qualifier="1" + qualifier = evalQualifier(qualifier) + if qualifier: + if not linenumber in testcases[testname]: + testcases[testname][linenumber]=[] + testcases[testname][linenumber].append(testtype) + + linenumber = linenumber + 1 + + inputfile.close() + return testcases + +def parseResults(output): + results = {} + for line in output: + print(line, end=' ') + + if line.count("SIGSEG"): + results[0] = ["FAULT", line.strip()] + continue + + # look for something of the form: + # filename:line:message + msg = line.split(":",2) + if len(msg)<3: continue + if msg[0]!=inputfilename: continue + if len(msg[1])==0: continue + if not msg[1][0] in string.digits: continue + + # it's in the right form; parse it + linenumber = int(msg[1]) + msgtype = "UNKNOWN" + uppermsg = msg[2].upper() + if uppermsg.count("ERROR"): + msgtype = "ERROR" + if uppermsg.count("WARNING"): + msgtype = "WARNING" + msgtext = msg[2].strip() + ignore = 0 + for ignoreExpr in ignoreExprList: + if re.search(ignoreExpr,msgtext)!=None: + ignore = 1 + if not ignore: + results[linenumber]=[msgtype,msg[2].strip()] + return results + +def showUsage(): + print("Usage: test testmode cfile [objectfile]") + print("Choices for testmode are:") + for testmodename in list(testmodes.keys()): + print(" %s" % testmodename) + sys.exit(1) + +# Start here +if len(sys.argv)<3: + showUsage() + +testmodename = sys.argv[1] +if not testmodename in testmodes: + print("Unknown test mode '%s'" % testmodename) + showUsage() + +testmode = testmodes[testmodename] +compilermode = testmode["compiler"] +port = expandPyExpr(testmode["port"]) +cc = expandPyExpr(compilermode["CC"]) +ccflags = expandPyExpr(compilermode["CCFLAGS"]) +if "flags" in testmode: + ccflags = " ".join([ccflags,expandPyExpr(testmode["flags"])]) +if len(sys.argv)>=4: + if "CCOUTPUT" in compilermode: + ccflags = " ".join([ccflags,expandPyExpr(compilermode["CCOUTPUT"]),sys.argv[3]]) +if len(sys.argv)>=5: + if "CCINCLUDEDIR" in compilermode: + ccflags = " ".join([ccflags,expandPyExpr(compilermode["CCINCLUDEDIR"]),sys.argv[4]]) +if "defined" in compilermode: + addDefines(compilermode["defined"], False) +if "defined" in testmode: + addDefines(testmode["defined"], False) +if "extra-defines" in compilermode: + addDefines(compilermode["extra-defines"], True) +if "extra-defines" in testmode: + addDefines(testmode["extra-defines"], True) +if "ignoremsg" in compilermode: + ignoreExprList = compilermode["ignoremsg"] +else: + ignoreExprList = [] + +inputfilename = sys.argv[2] +inputfilenameshort = os.path.basename(inputfilename) + +try: + testcases = parseInputfile(inputfilename) +except IOError: + print("Unable to read file '%s'" % inputfilename) + sys.exit(1) + +casecount = len(list(testcases.keys())) +testcount = 0 +failurecount = 0 + +print("--- Running: %s " % inputfilenameshort) +for testname in list(testcases.keys()): + if testname.find("DISABLED")>=0: + continue + ccdef = compilermode["CCDEF"]+testname + for extradef in list(extramacrodefs.keys()): + ccdef = ccdef + " " + compilermode["CCDEF"] + extradef + "=" + extramacrodefs[extradef] + if testname[-3:] == "C89": + ccstd = compilermode["C89"] + elif testname[-3:] == "C99": + ccstd = compilermode["C99"] + else: + ccstd = "" + cmd = " ".join([cc,ccflags,ccstd,ccdef,inputfilename]) + print() + print(cmd) + spawn = Popen(args=cmd.split(), bufsize=-1, stdout = PIPE, stderr = STDOUT, close_fds=True) + (stdoutdata,stderrdata) = spawn.communicate() + if not isinstance(stdoutdata, str): # python 3 returns bytes so + stdoutdata = str(stdoutdata,"utf-8") # convert to str type first + output = stdoutdata.splitlines(True) + + results = parseResults(output) + + if len(testcases[testname])==0: + testcount = testcount + 1 #implicit test for no errors + + # Go through the tests of this case and make sure + # the compiler gave a diagnostic + for checkline in list(testcases[testname].keys()): + testcount = testcount + 1 + if checkline in results: + if "IGNORE" in testcases[testname][checkline]: + testcount = testcount - 1 #this isn't really a test + del results[checkline] + else: + for wanted in testcases[testname][checkline]: + if not wanted=="IGNORE": + print("--- FAIL: expected %s" % wanted, end=' ') + print("at %s:%d" % (inputfilename, checkline)) + failurecount = failurecount + 1 + + # Output any unexpected diagnostics + for checkline in list(results.keys()): + print('--- FAIL: unexpected message "%s" ' % results[checkline][1], end=' ') + print("at %s:%d" % (inputfilename, checkline)) + failurecount = failurecount + 1 + +print() +print("--- Summary: %d/%d/%d: " % (failurecount, testcount, casecount), end=' ') +print("%d failed of %d tests in %d cases." % (failurecount, testcount, casecount)) |
