Merge branch 'master' into underscores
This commit is contained in:
@@ -5,25 +5,31 @@ ifneq ($(shell echo),)
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
S = $(subst /,\,/)
|
||||
EXE = .exe
|
||||
MKDIR = mkdir $(subst /,\,$1)
|
||||
RMDIR = -rmdir /q /s $(subst /,\,$1)
|
||||
TRUE = exit 0
|
||||
CAT = type $(subst /,\,$1)
|
||||
else
|
||||
S = /
|
||||
EXE =
|
||||
MKDIR = mkdir -p $1
|
||||
RMDIR = $(RM) -r $1
|
||||
TRUE = true
|
||||
CAT = cat $1
|
||||
endif
|
||||
|
||||
ifdef QUIET
|
||||
# .SILENT:
|
||||
endif
|
||||
|
||||
CA65 := $(if $(wildcard ../../../bin/ca65*),../../../bin/ca65,ca65)
|
||||
LD65 := $(if $(wildcard ../../../bin/ld65*),../../../bin/ld65,ld65)
|
||||
CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65)
|
||||
LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65)
|
||||
|
||||
WORKDIR = ../../../testwrk/asm/listing
|
||||
|
||||
ISEQUAL = ../../../testwrk/isequal$(EXE)
|
||||
ISEQUAL = ..$S..$S..$Stestwrk$Sisequal$(EXE)
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -O2
|
||||
@@ -50,14 +56,14 @@ $(WORKDIR)/$1.bin: $1.s $(ISEQUAL)
|
||||
|
||||
# compile without generating listing
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
$(CA65) -t none -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2>&1
|
||||
$(CA65) -t none -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2>&1
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
endif
|
||||
else
|
||||
$(CA65) -t none -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2>&1 || true
|
||||
$(CA65) -t none -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2) || $(TRUE)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2>&1 || true
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -67,18 +73,25 @@ else
|
||||
$(ISEQUAL) --empty $$(@:.bin=.err)
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard ref/$1.err2-ref),)
|
||||
$(ISEQUAL) ref/$1.err2-ref $$(@:.bin=.err2)
|
||||
else
|
||||
$(ISEQUAL) --empty $$(@:.bin=.err2)
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard ref/$1.bin-ref),)
|
||||
$(ISEQUAL) --binary ref/$1.bin-ref $$@
|
||||
endif
|
||||
|
||||
# rem $(indfo $(CAT) $(subst /,$$S,$$$(@:.bin=.ld65-err)))
|
||||
|
||||
ifneq ($(wildcard ref/$1.ld65err-ref),)
|
||||
@echo cat $$(@:.bin=.ld65-err)
|
||||
cat $$(@:.bin=.ld65-err)
|
||||
@echo
|
||||
@echo
|
||||
@echo $(CAT) $$(@:.bin=.ld65-err)
|
||||
# FIXME: somehow this refuses to work in cmd.exe
|
||||
ifndef CMD_EXE
|
||||
$(call CAT,$$(@:.bin=.ld65-err))
|
||||
-diff -u ref/$1.ld65err-ref $$(@:.bin=.ld65-err)
|
||||
@echo
|
||||
@echo
|
||||
endif
|
||||
$(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.ld65-err)
|
||||
else
|
||||
ifneq ($(wildcard $(WORKDIR)/$1.ld65-err),)
|
||||
@@ -86,16 +99,30 @@ ifneq ($(wildcard $(WORKDIR)/$1.ld65-err),)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard ref/$1.ld65err2-ref),)
|
||||
@echo $(CAT) $$(@:.bin=.ld65-err2)
|
||||
# FIXME: somehow this refuses to work in cmd.exe
|
||||
ifndef CMD_EXE
|
||||
$(call CAT,$$(@:.bin=.ld65-err2))
|
||||
-diff -u ref/$1.ld65err2-ref $$(@:.bin=.ld65-err2)
|
||||
endif
|
||||
$(ISEQUAL) --wildcards ref/$1.ld65err2-ref $$(@:.bin=.ld65-err2)
|
||||
else
|
||||
ifneq ($(wildcard $(WORKDIR)/$1.ld65-err2),)
|
||||
$(ISEQUAL) --empty $$(@:.bin=.ld65-err2)
|
||||
endif
|
||||
endif
|
||||
|
||||
# compile with listing file
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
$(CA65) -t none -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2>&1
|
||||
$(CA65) -t none -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2>&1
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
endif
|
||||
else
|
||||
$(CA65) -t none -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2>&1 || true
|
||||
$(CA65) -t none -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2) || $(TRUE)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2>&1 || true
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -113,10 +140,26 @@ ifneq ($(wildcard $(WORKDIR)/$1.list-ld65-err),)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard ref/$1.err2-ref),)
|
||||
$(ISEQUAL) ref/$1.err2-ref $$(@:.bin=.list-err2)
|
||||
else
|
||||
$(ISEQUAL) --empty $$(@:.bin=.list-err2)
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard ref/$1.ld65err2-ref),)
|
||||
$(ISEQUAL) --wildcards ref/$1.ld65err2-ref $$(@:.bin=.list-ld65-err2)
|
||||
else
|
||||
ifneq ($(wildcard $(WORKDIR)/$1.list-ld65-err2),)
|
||||
$(ISEQUAL) --empty $$(@:.bin=.list-ld65-err2)
|
||||
endif
|
||||
endif
|
||||
|
||||
# check if the result bin is the same as without listing file
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
ifeq ($(wildcard control/$1.err2),)
|
||||
$(ISEQUAL) $$@ $$(@:.bin=.list-bin)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard ref/$1.list-ref),)
|
||||
# we have a reference file, compare that, too
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
.paramcount = 3
|
||||
.paramcount = 5
|
||||
010-paramcount.s:18: Warning: User warning: r1 is blank!
|
||||
010-paramcount.s:14: Note: Macro was defined here
|
||||
010-paramcount.s:8: Note: Macro was defined here
|
||||
.paramcount = 3
|
||||
.paramcount = 5
|
||||
010-paramcount.s:19: Warning: User warning: r1 is blank!
|
||||
010-paramcount.s:14: Note: Macro was defined here
|
||||
010-paramcount.s:8: Note: Macro was defined here
|
||||
.paramcount = 1
|
||||
.paramcount = 5
|
||||
010-paramcount.s:20: Warning: User warning: r1 is blank!
|
||||
010-paramcount.s:14: Note: Macro was defined here
|
||||
010-paramcount.s:8: Note: Macro was defined here
|
||||
|
||||
9
test/asm/listing/ref/010-paramcount.err2-ref
Normal file
9
test/asm/listing/ref/010-paramcount.err2-ref
Normal file
@@ -0,0 +1,9 @@
|
||||
010-paramcount.s:18: Warning: User warning: r1 is blank!
|
||||
010-paramcount.s:14: Note: Macro was defined here
|
||||
010-paramcount.s:8: Note: Macro was defined here
|
||||
010-paramcount.s:19: Warning: User warning: r1 is blank!
|
||||
010-paramcount.s:14: Note: Macro was defined here
|
||||
010-paramcount.s:8: Note: Macro was defined here
|
||||
010-paramcount.s:20: Warning: User warning: r1 is blank!
|
||||
010-paramcount.s:14: Note: Macro was defined here
|
||||
010-paramcount.s:8: Note: Macro was defined here
|
||||
9
test/err/bug1890.c
Normal file
9
test/err/bug1890.c
Normal file
@@ -0,0 +1,9 @@
|
||||
/* bug #1890 - Overflow in enumerator value is not detected */
|
||||
|
||||
#include <limits.h>
|
||||
enum { a = ULONG_MAX, b } c = b;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
8
test/err/bug1893.c
Normal file
8
test/err/bug1893.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/* bug #1893 - Compiler accepts a ternary expression where it shouldn't */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int a, b, c;
|
||||
a == 1? b : c = 3;
|
||||
return 0;
|
||||
}
|
||||
5
test/err/bug1895-assign1a.c
Normal file
5
test/err/bug1895-assign1a.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_1_A
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign1b.c
Normal file
5
test/err/bug1895-assign1b.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_1_B
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign2a.c
Normal file
5
test/err/bug1895-assign2a.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_2_A
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign2b.c
Normal file
5
test/err/bug1895-assign2b.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_2_B
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign4a.c
Normal file
5
test/err/bug1895-assign4a.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_4_A
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign4b.c
Normal file
5
test/err/bug1895-assign4b.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_4_B
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign5a.c
Normal file
5
test/err/bug1895-assign5a.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_5_A
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-assign5b.c
Normal file
5
test/err/bug1895-assign5b.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_1_SUB_5_B
|
||||
|
||||
#include "bug1895-common.h"
|
||||
196
test/err/bug1895-common.h
Normal file
196
test/err/bug1895-common.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types
|
||||
|
||||
Test of incompatible pointer/array types in assignment ans conditional
|
||||
expressions, as well as function prototypes.
|
||||
|
||||
In each source file, define a single macro and include this file to perform
|
||||
a coresponding test individually.
|
||||
|
||||
https://github.com/cc65/cc65/issues/1895
|
||||
*/
|
||||
|
||||
/* Test 1 suite */
|
||||
#ifdef DO_TEST_1_SUB_1_A
|
||||
#define TEST_1_SUB_1_A CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_1_A BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_1_B
|
||||
#define TEST_1_SUB_1_B CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_1_B BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_2_A
|
||||
#define TEST_1_SUB_2_A CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_2_A BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_2_B
|
||||
#define TEST_1_SUB_2_B CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_2_B BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_4_A
|
||||
#define TEST_1_SUB_4_A CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_4_A BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_4_B
|
||||
#define TEST_1_SUB_4_B CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_4_B BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_5_A
|
||||
#define TEST_1_SUB_5_A CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_5_A BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_1_SUB_5_B
|
||||
#define TEST_1_SUB_5_B CMP_TYPES_1
|
||||
#else
|
||||
#define TEST_1_SUB_5_B BLANK
|
||||
#endif
|
||||
|
||||
/* Test 2 suite */
|
||||
#ifdef DO_TEST_2_SUB_1
|
||||
#define TEST_2_SUB_1 CMP_TYPES_2
|
||||
#else
|
||||
#define TEST_2_SUB_1 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_2_SUB_2
|
||||
#define TEST_2_SUB_2 CMP_TYPES_2
|
||||
#else
|
||||
#define TEST_2_SUB_2 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_2_SUB_3
|
||||
#define TEST_2_SUB_3 CMP_TYPES_2
|
||||
#else
|
||||
#define TEST_2_SUB_3 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_2_SUB_4
|
||||
#define TEST_2_SUB_4 CMP_TYPES_2
|
||||
#else
|
||||
#define TEST_2_SUB_4 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_2_SUB_5
|
||||
#define TEST_2_SUB_5 CMP_TYPES_2
|
||||
#else
|
||||
#define TEST_2_SUB_5 BLANK
|
||||
#endif
|
||||
|
||||
/* Test 3 suite */
|
||||
#ifdef DO_TEST_3_SUB_1
|
||||
#define TEST_3_SUB_1 CMP_TYPES_3
|
||||
#else
|
||||
#define TEST_3_SUB_1 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_3_SUB_2
|
||||
#define TEST_3_SUB_2 CMP_TYPES_3
|
||||
#else
|
||||
#define TEST_3_SUB_2 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_3_SUB_3
|
||||
#define TEST_3_SUB_3 CMP_TYPES_3
|
||||
#else
|
||||
#define TEST_3_SUB_3 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_3_SUB_4
|
||||
#define TEST_3_SUB_4 CMP_TYPES_3
|
||||
#else
|
||||
#define TEST_3_SUB_4 BLANK
|
||||
#endif
|
||||
|
||||
#ifdef DO_TEST_3_SUB_5
|
||||
#define TEST_3_SUB_5 CMP_TYPES_3
|
||||
#else
|
||||
#define TEST_3_SUB_5 BLANK
|
||||
#endif
|
||||
|
||||
/* Implementation */
|
||||
#define CONCAT(a, b) CONCAT_impl_(a, b)
|
||||
#define CONCAT_impl_(a, b) a##b
|
||||
#define BLANK(...)
|
||||
#define DECL_FUNCS(A, B)\
|
||||
void CONCAT(foo_,__LINE__)(A); void CONCAT(foo_,__LINE__)(B);
|
||||
|
||||
/* Test with assignment */
|
||||
#define CMP_TYPES_1(A, B)\
|
||||
do {\
|
||||
A p; B q;\
|
||||
_Pragma("warn(error, on)")\
|
||||
p = q;\
|
||||
_Pragma("warn(error, off)")\
|
||||
} while (0)
|
||||
|
||||
/* Test with conditional expression */
|
||||
#define CMP_TYPES_2(A, B)\
|
||||
do {\
|
||||
A p; B q;\
|
||||
_Pragma("warn(error, on)")\
|
||||
v = v ? p : q;\
|
||||
_Pragma("warn(error, off)")\
|
||||
} while (0)
|
||||
|
||||
/* Test with function prototype */
|
||||
#define CMP_TYPES_3(A, B)\
|
||||
do {\
|
||||
DECL_FUNCS(A,B);\
|
||||
} while (0)
|
||||
|
||||
static void *v;
|
||||
|
||||
typedef int (*p1)[3]; /* pointer to array */
|
||||
typedef int **q1; /* pointer to pointer */
|
||||
typedef int (**p2)[3]; /* pointer to pointer to array */
|
||||
typedef int ***q2; /* pointer to pointer to pointer */
|
||||
typedef int p3[1][3]; /* array of array */
|
||||
typedef int *q3[1]; /* array of pointer */
|
||||
typedef int const **p4; /* pointer to pointer to const */
|
||||
typedef int **q4; /* pointer to pointer to non-const */
|
||||
typedef int (*p5)(int (*)(p3)); /* pointer to function taking pointer to function taking pointer to array */
|
||||
typedef int (*q5)(int (*)(q3)); /* pointer to function taking pointer to function taking pointer to pointer */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Warnings */
|
||||
TEST_1_SUB_1_A(p1, q1);
|
||||
TEST_1_SUB_1_B(q1, p1);
|
||||
TEST_1_SUB_2_A(p2, q2);
|
||||
TEST_1_SUB_2_B(q2, p2);
|
||||
/* TEST_1_SUB_3_A(p3, q3); */
|
||||
/* TEST_1_SUB_3_B(q3, p3); */
|
||||
TEST_1_SUB_4_A(p4, q4);
|
||||
TEST_1_SUB_4_B(q4, p4);
|
||||
TEST_1_SUB_5_A(p5, q5);
|
||||
TEST_1_SUB_5_B(q5, p5);
|
||||
|
||||
/* GCC and clang give warnings while cc65 gives errors */
|
||||
TEST_2_SUB_1(p1, q1);
|
||||
TEST_2_SUB_2(p2, q2);
|
||||
TEST_2_SUB_3(p3, q3);
|
||||
TEST_2_SUB_4(p4, q4);
|
||||
TEST_2_SUB_5(p5, q5);
|
||||
|
||||
/* Errors */
|
||||
TEST_3_SUB_1(p1, q1);
|
||||
TEST_3_SUB_2(p2, q2);
|
||||
TEST_3_SUB_3(p3, q3);
|
||||
TEST_3_SUB_4(p4, q4);
|
||||
TEST_3_SUB_5(p5, q5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
5
test/err/bug1895-cond1.c
Normal file
5
test/err/bug1895-cond1.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_2_SUB_1
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-cond2.c
Normal file
5
test/err/bug1895-cond2.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_2_SUB_2
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-cond3.c
Normal file
5
test/err/bug1895-cond3.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_2_SUB_3
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-cond4.c
Normal file
5
test/err/bug1895-cond4.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_2_SUB_4
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-cond5.c
Normal file
5
test/err/bug1895-cond5.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_2_SUB_5
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-prototype1.c
Normal file
5
test/err/bug1895-prototype1.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_1
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-prototype2.c
Normal file
5
test/err/bug1895-prototype2.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_2
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-prototype3.c
Normal file
5
test/err/bug1895-prototype3.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_3
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-prototype4.c
Normal file
5
test/err/bug1895-prototype4.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_4
|
||||
|
||||
#include "bug1895-common.h"
|
||||
5
test/err/bug1895-prototype5.c
Normal file
5
test/err/bug1895-prototype5.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_5
|
||||
|
||||
#include "bug1895-common.h"
|
||||
@@ -59,9 +59,9 @@ $(ISEQUAL): ../isequal.c | $(WORKDIR)
|
||||
define PRG_template
|
||||
|
||||
# should compile, but gives an error
|
||||
$(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR)
|
||||
$(WORKDIR)/int-static-1888.$1.$2.prg: int-static-1888.c | $(WORKDIR)
|
||||
@echo "FIXME: " $$@ "currently does not compile."
|
||||
$(if $(QUIET),echo misc/bug1768.$1.$2.prg)
|
||||
$(if $(QUIET),echo misc/int-static-1888.$1.$2.prg)
|
||||
$(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR)
|
||||
|
||||
# should compile, but gives an error
|
||||
@@ -132,6 +132,14 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR)
|
||||
$(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR)
|
||||
$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR)
|
||||
|
||||
# this one requires -Werror
|
||||
$(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/bug1768.$1.$2.prg)
|
||||
$(CC65) -Werror -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR)
|
||||
$(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR)
|
||||
$(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR)
|
||||
$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR)
|
||||
|
||||
# should compile, but then hangs in an endless loop
|
||||
$(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/endless.$1.$2.prg)
|
||||
|
||||
@@ -1,14 +1,147 @@
|
||||
/*
|
||||
Copyright 2021-2022, The cc65 Authors
|
||||
|
||||
#include <stdlib.h>
|
||||
This software is provided "as-is", without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
int a = 1 || (8 / 0);
|
||||
int b = 0 && (8 % 0);
|
||||
int c = 1 ? 42 : (0 % 0);
|
||||
int d = 1 || a / 0;
|
||||
int e = 0 && b % 0;
|
||||
int f = 1 ? 42 : (a %= 0, b /= 0);
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications; and, to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated, but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
Test of operations in unevaluated context resulted from 'sizeof' and
|
||||
short-circuited code-paths in AND, OR and conditional operations.
|
||||
|
||||
See also:
|
||||
https://github.com/cc65/cc65/issues/1768#issuecomment-1175221466
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures;
|
||||
|
||||
#define TEST(EXPR)\
|
||||
{\
|
||||
int acc = 0;\
|
||||
acc += sizeof((EXPR), 0);\
|
||||
acc += (0 && (EXPR));\
|
||||
acc += (1 || (EXPR));\
|
||||
acc += (0 ? (EXPR) : 0);\
|
||||
acc += (1 ? 0 : (EXPR));\
|
||||
if (acc == 0) {\
|
||||
printf("acc = %d\n", acc);\
|
||||
++failures;\
|
||||
}\
|
||||
}
|
||||
|
||||
/* Division by zero/modulo with zero */
|
||||
void test_1(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
TEST((i / 0) | (j % 0))
|
||||
}
|
||||
|
||||
/* Division by zero/modulo with zero */
|
||||
void test_2(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
TEST((i /= 0) | (j %= 0))
|
||||
}
|
||||
|
||||
/* Shift by too wide counts */
|
||||
void test_3(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
TEST((i << 32) | (j >> 32))
|
||||
}
|
||||
|
||||
/* Shift by too wide counts */
|
||||
void test_4(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
TEST((i <<= 32) | (j >>= 32))
|
||||
}
|
||||
|
||||
/* Shift by negative counts */
|
||||
void test_5(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
TEST((i << -1) | (j >> -1))
|
||||
}
|
||||
|
||||
/* Shift by negative counts */
|
||||
void test_6(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
TEST((i <<= -1) | (j >>= -1))
|
||||
}
|
||||
|
||||
/* Shift bit-fields */
|
||||
void test_7(void)
|
||||
{
|
||||
struct S {
|
||||
long i : 24; /* Will be promoted to 32-bit integer in calculation */
|
||||
long j : 8; /* Will be promoted to 16-bit integer in calculation */
|
||||
} s;
|
||||
long k;
|
||||
|
||||
s.i = 1;
|
||||
printf("%u\n", sizeof(s.i << 24));
|
||||
s.i = 2;
|
||||
k = s.i << 16;
|
||||
if (k != 0x00020000L) {
|
||||
printf("k = %ld, expected: %ld\n", k, 0x00020000L);
|
||||
}
|
||||
TEST(s.j >> 16)
|
||||
}
|
||||
|
||||
/* Shift bit-fields */
|
||||
void test_8(void)
|
||||
{
|
||||
struct S {
|
||||
long i : 24; /* Will be promoted to 32-bit integer in calculation */
|
||||
long j : 8; /* Will be promoted to 16-bit integer in calculation */
|
||||
} s;
|
||||
long k;
|
||||
|
||||
s.i = 3;
|
||||
printf("%u\n", sizeof(s.i << 24));
|
||||
s.i = 4;
|
||||
k = s.i <<= 16;
|
||||
if (k != 0x00040000L) {
|
||||
printf("k = %ld, expected: %ld\n", k, 0x00040000L);
|
||||
}
|
||||
TEST(s.j >>= 8)
|
||||
}
|
||||
|
||||
/* Do all tests */
|
||||
int main(void)
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
test_1();
|
||||
test_2();
|
||||
test_3();
|
||||
test_4();
|
||||
test_5();
|
||||
test_6();
|
||||
test_7();
|
||||
test_8();
|
||||
|
||||
printf("Failures: %d\n", failures);
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,28 @@ compiler is working as expected (when the tests behave as described):
|
||||
library.
|
||||
|
||||
/ref - These tests produce output that must be compared with reference output.
|
||||
Normally the reference output is produced by compiling the program on the
|
||||
host (using gcc mostly) and then running them on the host. Tests should
|
||||
be tweaked to produce the same output as on the host in the cases where
|
||||
it would be different.
|
||||
|
||||
The Makefile also handles some special cases (add the tests to the
|
||||
respective list in the makefile):
|
||||
|
||||
- Sometimes we want to check the warnings produced by the compiler. In
|
||||
that case use the CUSTOMSOURCES list. Whatever output the compiler writes
|
||||
to stderr will be compared against the matching .cref file. There is an
|
||||
example in custom-reference.c/.cref
|
||||
|
||||
- Sometimes we want to check what kind of output the compiler produces
|
||||
for a file that does not compile. In that case use the ERRORSOURCES list.
|
||||
There is an example in custom-reference-error.c/.cref
|
||||
|
||||
Warning: please understand that comparing the compiler output against
|
||||
a reference produces a moving target, ie the tests may break randomly
|
||||
at any time when the compiler output changes for whatever reason. So
|
||||
only ever use this as a last resort when something can not be tested by
|
||||
other means.
|
||||
|
||||
/err - contains tests that MUST NOT compile
|
||||
|
||||
|
||||
@@ -11,12 +11,14 @@ ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
MKDIR = mkdir $(subst /,\,$1)
|
||||
RMDIR = -rmdir /s /q $(subst /,\,$1)
|
||||
COPY = copy $(subst /,\,$1) $(subst /,\,$2)
|
||||
else
|
||||
S = /
|
||||
EXE =
|
||||
NULLDEV = /dev/null
|
||||
MKDIR = mkdir -p $1
|
||||
RMDIR = $(RM) -r $1
|
||||
COPY = cp $1 $2
|
||||
endif
|
||||
|
||||
ifdef QUIET
|
||||
@@ -42,24 +44,48 @@ CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
# list of sources that produces warnings that we want to check. a .cref file
|
||||
# containing the exact output is required.
|
||||
CUSTOMSOURCES = \
|
||||
custom-reference.c
|
||||
|
||||
# list of sources that produce a compiler error. a .cref files containing the
|
||||
# exact error output is required
|
||||
ERRORSOURCES = \
|
||||
custom-reference-error.c \
|
||||
bug1889-missing-identifier.c
|
||||
|
||||
SOURCES := $(filter-out $(CUSTOMSOURCES) $(ERRORSOURCES),$(wildcard *.c))
|
||||
|
||||
REFS = $(SOURCES:%.c=$(WORKDIR)/%.ref)
|
||||
CUSTOMREFS = $(CUSTOMSOURCES:%.c=$(WORKDIR)/%.cref) $(ERRORSOURCES:%.c=$(WORKDIR)/%.cref)
|
||||
|
||||
TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg))
|
||||
TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg))
|
||||
|
||||
all: $(REFS) $(TESTS)
|
||||
CUSTOMTESTS = $(foreach option,$(OPTIONS),$(CUSTOMSOURCES:%.c=$(WORKDIR)/%.$(option).6502.custom.prg))
|
||||
CUSTOMTESTS += $(foreach option,$(OPTIONS),$(CUSTOMSOURCES:%.c=$(WORKDIR)/%.$(option).65c02.custom.prg))
|
||||
|
||||
ERRORTESTS = $(foreach option,$(OPTIONS),$(ERRORSOURCES:%.c=$(WORKDIR)/%.$(option).6502.error.prg))
|
||||
ERRORTESTS += $(foreach option,$(OPTIONS),$(ERRORSOURCES:%.c=$(WORKDIR)/%.$(option).65c02.error.prg))
|
||||
|
||||
all: $(CUSTOMREFS) $(REFS) $(TESTS) $(CUSTOMTESTS) $(ERRORTESTS)
|
||||
|
||||
$(WORKDIR):
|
||||
$(call MKDIR,$(WORKDIR))
|
||||
|
||||
$(ISEQUAL): ../isequal.c | $(WORKDIR)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(WORKDIR)/%.cref: %.cref | $(WORKDIR)
|
||||
$(if $(QUIET),echo ref/$*.cref)
|
||||
$(call COPY,$*.cref,$@)
|
||||
|
||||
$(WORKDIR)/%.ref: %.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo ref/$*.host)
|
||||
$(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(NULLERR)
|
||||
$(WORKDIR)$S$*.host > $@
|
||||
|
||||
$(ISEQUAL): ../isequal.c | $(WORKDIR)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
# "yaccdbg.c" includes "yacc.c".
|
||||
# yaccdbg's built files must depend on both of them.
|
||||
#
|
||||
@@ -78,8 +104,43 @@ $(WORKDIR)/%.$1.$2.prg: %.c $(WORKDIR)/%.ref $(ISEQUAL)
|
||||
|
||||
endef # PRG_template
|
||||
|
||||
# extra template for the case when compilation works, but we still want to
|
||||
# compare the warning output with our custom reference
|
||||
define PRG_custom_template
|
||||
|
||||
$(WORKDIR)/%.$1.$2.custom.prg: %.c $(WORKDIR)/%.ref %.c $(WORKDIR)/%.cref $(ISEQUAL)
|
||||
$(if $(QUIET),echo cref/$$*.$1.$2.custom.prg)
|
||||
-$(CC65) -t sim$2 $$(CC65FLAGS) -$1 -o $$(@:.custom.prg=.s) $$< 2> $(WORKDIR)/$$*.$1.$2.cout
|
||||
$(CA65) -t sim$2 -o $$(@:.custom.prg=.o) $$(@:.custom.prg=.s) $(NULLERR)
|
||||
$(LD65) -t sim$2 -o $$@ $$(@:.custom.prg=.o) sim$2.lib $(NULLERR)
|
||||
$(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.$1.$2.out
|
||||
$(ISEQUAL) $(WORKDIR)/$$*.$1.$2.cout $(WORKDIR)/$$*.cref
|
||||
$(ISEQUAL) $(WORKDIR)/$$*.$1.$2.out $(WORKDIR)/$$*.ref
|
||||
|
||||
endef # PRG_error_template
|
||||
|
||||
# extra template for the case when compilation fails, but we still want to
|
||||
# compare the error output with our custom reference
|
||||
define PRG_error_template
|
||||
|
||||
$(WORKDIR)/%.$1.$2.error.prg: %.c $(WORKDIR)/%.cref $(ISEQUAL)
|
||||
$(if $(QUIET),echo cref/$$*.$1.$2.error.prg)
|
||||
-$(CC65) -t sim$2 $$(CC65FLAGS) -$1 -o $$(@:.error.prg=.s) $$< 2> $(WORKDIR)/$$*.$1.$2.cout
|
||||
# $(CA65) -t sim$2 -o $$(@:.error.prg=.o) $$(@:.error.prg=.s) $(NULLERR)
|
||||
# $(LD65) -t sim$2 -o $$@ $$(@:.error.prg=.o) sim$2.lib $(NULLERR)
|
||||
# $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.$1.$2.out
|
||||
$(ISEQUAL) $(WORKDIR)/$$*.$1.$2.cout $(WORKDIR)/$$*.cref
|
||||
|
||||
endef # PRG_error_template
|
||||
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),6502)))
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02)))
|
||||
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_custom_template,$(option),6502)))
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_custom_template,$(option),65c02)))
|
||||
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_error_template,$(option),6502)))
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_error_template,$(option),65c02)))
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
9
test/ref/bug1889-missing-identifier.c
Normal file
9
test/ref/bug1889-missing-identifier.c
Normal file
@@ -0,0 +1,9 @@
|
||||
/* bug 1889 - endless errors due to failure in recovery from missing identifier */
|
||||
|
||||
int enum { a } x;
|
||||
inline enum { b };
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
3
test/ref/bug1889-missing-identifier.cref
Normal file
3
test/ref/bug1889-missing-identifier.cref
Normal file
@@ -0,0 +1,3 @@
|
||||
bug1889-missing-identifier.c:3: Error: Identifier expected
|
||||
bug1889-missing-identifier.c:4: Error: Identifier expected
|
||||
bug1889-missing-identifier.c:4: Warning: Implicit 'int' is an obsolete feature
|
||||
21
test/ref/custom-reference-error.c
Normal file
21
test/ref/custom-reference-error.c
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
/*
|
||||
this is an example (not actually a regression test) that shows how to
|
||||
make a check that compares the compiler (error-) output with a provided
|
||||
reference.
|
||||
|
||||
to produce a reference file, first make sure your program "works" as intended,
|
||||
then "make" in this directory once and copy the produced compiler output to
|
||||
the reference:
|
||||
|
||||
$ cp ../../testwrk/ref/custom-reference-error.g.6502.out custom-reference-error.cref
|
||||
|
||||
and then "make" again to confirm
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("%02x", 0x42);
|
||||
n = 0; /* produce an error */
|
||||
/* another error */
|
||||
}
|
||||
5
test/ref/custom-reference-error.cref
Normal file
5
test/ref/custom-reference-error.cref
Normal file
@@ -0,0 +1,5 @@
|
||||
custom-reference-error.c:18: Error: Call to undeclared function 'printf'
|
||||
custom-reference-error.c:19: Error: Undefined symbol: 'n'
|
||||
custom-reference-error.c:21: Warning: Control reaches end of non-void function [-Wreturn-type]
|
||||
custom-reference-error.c:21: Warning: Parameter 'argc' is never used
|
||||
custom-reference-error.c:21: Warning: Parameter 'argv' is never used
|
||||
24
test/ref/custom-reference.c
Normal file
24
test/ref/custom-reference.c
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
/*
|
||||
this is an example (not actually a regression test) that shows how to
|
||||
make a check that compares the compiler (error-) output with a provided
|
||||
reference.
|
||||
|
||||
to produce a reference file, first make sure your program "works" as intended,
|
||||
then "make" in this directory once and copy the produced compiler output to
|
||||
the reference:
|
||||
|
||||
$ cp ../../testwrk/ref/custom-reference.g.6502.out custom-reference.cref
|
||||
|
||||
and then "make" again to confirm
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("%02x", 0x42);
|
||||
/* produce a warning */
|
||||
return 0;
|
||||
}
|
||||
2
test/ref/custom-reference.cref
Normal file
2
test/ref/custom-reference.cref
Normal file
@@ -0,0 +1,2 @@
|
||||
custom-reference.c:24: Warning: Parameter 'argc' is never used
|
||||
custom-reference.c:24: Warning: Parameter 'argv' is never used
|
||||
@@ -564,9 +564,9 @@ int main (void)
|
||||
|
||||
/* Output the result */
|
||||
if (Failures) {
|
||||
printf ("%u tests, %u failures\n", Tests, Failures);
|
||||
printf ("sprintf-test: %u tests, %u failures\n", Tests, Failures);
|
||||
} else {
|
||||
printf ("%u tests: Ok\n", Tests);
|
||||
printf ("sprintf-test: %u tests: Ok\n", Tests);
|
||||
}
|
||||
|
||||
/* Wait for a key so we can read the result */
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
/* Bug #1408: Signed char type comparisons with unsigned numeric constants */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
static signed char x = -1;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (!(x > -2u)) {
|
||||
printf("x > -2u should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(x > 0u)) {
|
||||
printf("x > 0u should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(x > 255u)) {
|
||||
printf("x > 255u should be true\n");
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (!(-2u < x)) {
|
||||
printf("-2u < x should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(0u < x)) {
|
||||
printf("0u < x should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(255u < x)) {
|
||||
printf("255u < x should be true\n");
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (failures != 0) {
|
||||
printf("Failures: %d\n", failures);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
/* Bug #1408: Signed char type comparisons with unsigned numeric constants */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
static signed char x = -1;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (!(x > -2u)) {
|
||||
printf("x > -2u should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(x > 0u)) {
|
||||
printf("x > 0u should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(x > 255u)) {
|
||||
printf("x > 255u should be true\n");
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (!(-2u < x)) {
|
||||
printf("-2u < x should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(0u < x)) {
|
||||
printf("0u < x should be true\n");
|
||||
++failures;
|
||||
}
|
||||
if (!(255u < x)) {
|
||||
printf("255u < x should be true\n");
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (failures != 0) {
|
||||
printf("Failures: %d\n", failures);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
/* Bug #1451 - local struct field access via the address of the struct */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
} S;
|
||||
|
||||
int failures = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
S a = {2, 5};
|
||||
S b = {1, 4};
|
||||
S m[1] = {{6, 3}};
|
||||
S *p = &a;
|
||||
|
||||
(&a)->a += b.a;
|
||||
p->b += b.b;
|
||||
m->a += b.a;
|
||||
|
||||
if ((&a)->a != 3) {
|
||||
++failures;
|
||||
printf("Expected 3, got %d\n", (&a)->a);
|
||||
}
|
||||
|
||||
if (p->b != 9) {
|
||||
++failures;
|
||||
printf("Expected 9, got %d\n", p->b);
|
||||
}
|
||||
|
||||
if (m->a != 7) {
|
||||
++failures;
|
||||
printf("Expected 7, got %d\n", m->a);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
/* Bug #1451 - local struct field access via the address of the struct */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
} S;
|
||||
|
||||
int failures = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
S a = {2, 5};
|
||||
S b = {1, 4};
|
||||
S m[1] = {{6, 3}};
|
||||
S *p = &a;
|
||||
|
||||
(&a)->a += b.a;
|
||||
p->b += b.b;
|
||||
m->a += b.a;
|
||||
|
||||
if ((&a)->a != 3) {
|
||||
++failures;
|
||||
printf("Expected 3, got %d\n", (&a)->a);
|
||||
}
|
||||
|
||||
if (p->b != 9) {
|
||||
++failures;
|
||||
printf("Expected 9, got %d\n", p->b);
|
||||
}
|
||||
|
||||
if (m->a != 7) {
|
||||
++failures;
|
||||
printf("Expected 7, got %d\n", m->a);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/* issue #1462 - Bit-fields are still broken */
|
||||
/* More tests on "op= expression result value" that a naive fix might fail with */
|
||||
/* When (un-)signedness involves with integral promotion */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
@@ -1,12 +1,12 @@
|
||||
/* bug #1643, macro expansion in #include */
|
||||
|
||||
#define MKSTR(a) MKSTR_IMPL(a)
|
||||
#define MKSTR_IMPL(a) #a
|
||||
#define BUG1643_H bug1643.h
|
||||
|
||||
#include MKSTR(BUG1643_H)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return BUG1643_RESULT;
|
||||
}
|
||||
/* bug #1643, macro expansion in #include */
|
||||
|
||||
#define MKSTR(a) MKSTR_IMPL(a)
|
||||
#define MKSTR_IMPL(a) #a
|
||||
#define BUG1643_H bug1643.h
|
||||
|
||||
#include MKSTR(BUG1643_H)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return BUG1643_RESULT;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* bug #1643, macro expansion in #include */
|
||||
|
||||
#define STDIO_H <stdio.h>
|
||||
#include STDIO_H
|
||||
|
||||
#ifdef string
|
||||
#undef string
|
||||
#endif
|
||||
|
||||
#define string 0!%^&*/_=
|
||||
#include <string.h>
|
||||
|
||||
#define BUG1643_RESULT 0
|
||||
/* bug #1643, macro expansion in #include */
|
||||
|
||||
#define STDIO_H <stdio.h>
|
||||
#include STDIO_H
|
||||
|
||||
#ifdef string
|
||||
#undef string
|
||||
#endif
|
||||
|
||||
#define string 0!%^&*/_=
|
||||
#include <string.h>
|
||||
|
||||
#define BUG1643_RESULT 0
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/* OptCmp1 messed up with labels */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
static unsigned int z = 0xFF23;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
register unsigned int x = 0x200;
|
||||
register unsigned int y = 0;
|
||||
|
||||
do {
|
||||
++y;
|
||||
} while (--x);
|
||||
if (y != 0x200) {
|
||||
printf("y should be 0x200, not 0x%X.\n", y);
|
||||
++failures;;
|
||||
}
|
||||
|
||||
if ((z -= 0x23)) {
|
||||
/* Passed -- non-zero z looks like non-zero. */
|
||||
} else {
|
||||
/* Failed -- only the low byte of z was tested. */
|
||||
printf("Test thinks non-zero z is zero.\n");
|
||||
++failures;
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
/* OptCmp1 messed up with labels */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
static unsigned int z = 0xFF23;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
register unsigned int x = 0x200;
|
||||
register unsigned int y = 0;
|
||||
|
||||
do {
|
||||
++y;
|
||||
} while (--x);
|
||||
if (y != 0x200) {
|
||||
printf("y should be 0x200, not 0x%X.\n", y);
|
||||
++failures;;
|
||||
}
|
||||
|
||||
if ((z -= 0x23)) {
|
||||
/* Passed -- non-zero z looks like non-zero. */
|
||||
} else {
|
||||
/* Failed -- only the low byte of z was tested. */
|
||||
printf("Test thinks non-zero z is zero.\n");
|
||||
++failures;
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/* Bug #1822 - Redefined macros failed to be all undefined with a single #undef */
|
||||
|
||||
#undef F
|
||||
#undef F
|
||||
|
||||
#define F 1
|
||||
#define F 1
|
||||
|
||||
#undef F
|
||||
#if defined F
|
||||
#error #undef F fails!
|
||||
#endif
|
||||
|
||||
#define F 0
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (F != 0)
|
||||
{
|
||||
printf("failed: F = %d\n", F);
|
||||
}
|
||||
return F;
|
||||
}
|
||||
/* Bug #1822 - Redefined macros failed to be all undefined with a single #undef */
|
||||
|
||||
#undef F
|
||||
#undef F
|
||||
|
||||
#define F 1
|
||||
#define F 1
|
||||
|
||||
#undef F
|
||||
#if defined F
|
||||
#error #undef F fails!
|
||||
#endif
|
||||
|
||||
#define F 0
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (F != 0)
|
||||
{
|
||||
printf("failed: F = %d\n", F);
|
||||
}
|
||||
return F;
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
/* Bug 1838 - function parameters declared as function types rather than function pointers */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
|
||||
typedef int fn_t(int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
void foo(fn_t*);
|
||||
fn_t bar;
|
||||
|
||||
foo(bar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void foo(int func(int))
|
||||
{
|
||||
int n = func(42);
|
||||
|
||||
if (n != 12) {
|
||||
printf("n = %d, expected: 12\n", n);
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
|
||||
int bar(int a)
|
||||
{
|
||||
if (a != 42) {
|
||||
printf("a = %d, expected: 42\n", a);
|
||||
++failures;
|
||||
}
|
||||
return 12;
|
||||
}
|
||||
/* Bug 1838 - function parameters declared as function types rather than function pointers */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
|
||||
typedef int fn_t(int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
void foo(fn_t*);
|
||||
fn_t bar;
|
||||
|
||||
foo(bar);
|
||||
return failures;
|
||||
}
|
||||
|
||||
void foo(int func(int))
|
||||
{
|
||||
int n = func(42);
|
||||
|
||||
if (n != 12) {
|
||||
printf("n = %d, expected: 12\n", n);
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
|
||||
int bar(int a)
|
||||
{
|
||||
if (a != 42) {
|
||||
printf("a = %d, expected: 42\n", a);
|
||||
++failures;
|
||||
}
|
||||
return 12;
|
||||
}
|
||||
|
||||
46
test/val/bug1847-struct-field-access.c
Normal file
46
test/val/bug1847-struct-field-access.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/* Bug #1847 - struct field access */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct TestStruct {
|
||||
char a;
|
||||
char b;
|
||||
char c;
|
||||
};
|
||||
|
||||
struct TestStruct s0[2] = { {0xFF, 0, 0xFF}, {0, 0x42, 0xFF} };
|
||||
struct TestStruct* s0Ptr = s0;
|
||||
|
||||
#define TEST_READ_SUB(X, E) \
|
||||
if ((X) != (E)) { \
|
||||
printf(#X ": 0x%X, expected: 0x%X\n", (X), (E)); \
|
||||
++failures; \
|
||||
}
|
||||
|
||||
#define TEST_READ(S, I, F, E) \
|
||||
TEST_READ_SUB(S[I].F, E) \
|
||||
TEST_READ_SUB((&S[I])->F, E) \
|
||||
TEST_READ_SUB((&S[I])[0].F, E) \
|
||||
TEST_READ_SUB(S##Ptr[I].F, E) \
|
||||
TEST_READ_SUB((&S##Ptr[I])->F, E) \
|
||||
TEST_READ_SUB((&(S##Ptr[I]))[0].F, E) \
|
||||
TEST_READ_SUB((&(*S##Ptr))[I].F, E) \
|
||||
TEST_READ_SUB((&(*S##Ptr)+I)->F, E) \
|
||||
TEST_READ_SUB((S##Ptr+I)->F, E) \
|
||||
TEST_READ_SUB((S##Ptr+I)[0].F, E)
|
||||
|
||||
static unsigned failures = 0;
|
||||
|
||||
int main(void) {
|
||||
struct TestStruct s1[2] = { {0xFF, 0, 0xFF}, {0, 42, 0xFF} };
|
||||
struct TestStruct* s1Ptr = s1;
|
||||
|
||||
TEST_READ(s0, 1, b, 0x42)
|
||||
TEST_READ(s1, 1, b, 42)
|
||||
|
||||
if (failures > 0) {
|
||||
printf("Failures: %u\n", failures);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
21
test/val/bug1853-inline-asm.c
Normal file
21
test/val/bug1853-inline-asm.c
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
/* #1853 - Regression on inline assembly expression evaluation */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/*
|
||||
compiles with e.g. Git 2f4e2a3 to the expected
|
||||
|
||||
lda 1
|
||||
lda 1 + 1
|
||||
rts
|
||||
|
||||
However, with the current HEAD, it compiles to
|
||||
|
||||
lda 1
|
||||
lda
|
||||
*/
|
||||
__asm__("lda 1");
|
||||
__asm__("lda 1 + 1");
|
||||
return 0;
|
||||
}
|
||||
19
test/val/bug1891.c
Normal file
19
test/val/bug1891.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* bug #1891 - backslash/newline sequence in string constants is treated wrong */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
const char* a = "hello \
|
||||
world";
|
||||
const char* b = \
|
||||
"hello world";
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (strcmp(a, b) != 0) {
|
||||
printf("a:\n%s\n", a);
|
||||
printf("b:\n%s\n", b);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
160
test/val/const-side-effect.c
Normal file
160
test/val/const-side-effect.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/* Check code generation for constant operands with side-effects */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
|
||||
#define TEST(X, Y, L) \
|
||||
if (x != X || y != Y) { \
|
||||
printf("Failed: " L "\nExpected: x = " #X ", y = " #Y ", got: x = %d, y = %d\n\n", x, y); \
|
||||
++failures; \
|
||||
}
|
||||
|
||||
#define TEST_LINE_UNARY(OP, RH, ID) \
|
||||
"x = " #OP "(set(&y, " #ID "), " #RH ")"
|
||||
|
||||
#define TEST_UNARY(OP, RH, RS, ID) \
|
||||
x = -!(RS), y = -!(RS); \
|
||||
x = OP (set(&y, ID), RH); \
|
||||
TEST(RS, ID, TEST_LINE_UNARY(OP, RH, ID))
|
||||
|
||||
#define TEST_LINE_RHS_EFFECT(LH, OP, RH, ID) \
|
||||
"x = " #LH " " #OP " (set(&y, " #ID "), " #RH ")"
|
||||
|
||||
#define TEST_LINE_LHS_EFFECT(LH, OP, RH, ID) \
|
||||
"y = (set(&x, " #ID "), " #LH ") " #OP " " #RH
|
||||
|
||||
#define TEST_BINARY(LH, OP, RH, RS, ID) \
|
||||
x = -!(RS), y = -!(RS); \
|
||||
x = LH OP (set(&y, ID), RH); \
|
||||
TEST(RS, ID, TEST_LINE_RHS_EFFECT(LH, OP, RH, ID)) \
|
||||
y = -!(RS), x = -!(RS); \
|
||||
y = (set(&x, ID), LH) OP RH; \
|
||||
TEST(ID, RS, TEST_LINE_LHS_EFFECT(LH, OP, RH, ID)) \
|
||||
y = -!(RS); \
|
||||
x = (set(&x, LH), x) OP (set(&y, ID), RH); \
|
||||
TEST(RS, ID, TEST_LINE_RHS_EFFECT((set(&x, LH), x), OP, RH, ID)) \
|
||||
x = -!(RS); \
|
||||
y = (set(&x, ID), LH) OP (set(&y, RH), y); \
|
||||
TEST(ID, RS, TEST_LINE_LHS_EFFECT(LH, OP, (set(&y, RH), y), ID))
|
||||
|
||||
#define TEST_LINE_RHS_EFFECT_WITH_CAST(LT, LH, OP, RT, RH, ID) \
|
||||
"x = (" #LT ")" #LH " " #OP " (" #RT ")(set(&y, " #ID "), " #RH ")"
|
||||
|
||||
#define TEST_LINE_LHS_EFFECT_WITH_CAST(LT, LH, OP, RT, RH, ID) \
|
||||
"y = (" #LT ")(set(&x, " #ID "), " #LH ") " #OP " (" #RT ")" #RH
|
||||
|
||||
#define TEST_BINARY_WITH_CAST(LT, LH, OP, RT, RH, RS, ID) \
|
||||
x = -!(RS), y = -!(RS); \
|
||||
x = (LT)LH OP (RT)(set(&y, ID), RH); \
|
||||
TEST(RS, ID, TEST_LINE_RHS_EFFECT_WITH_CAST(LT, LH, OP, RT, RH, ID)) \
|
||||
y = -!(RS), x = -!(RS); \
|
||||
y = (LT)(set(&x, ID), LH) OP (RT)RH; \
|
||||
TEST(ID, RS, TEST_LINE_LHS_EFFECT_WITH_CAST(LT, LH, OP, RT, RH, ID)) \
|
||||
y = -!(RS); \
|
||||
x = (LT)(set(&x, LH), x) OP (RT)(set(&y, ID), RH); \
|
||||
TEST(RS, ID, TEST_LINE_RHS_EFFECT_WITH_CAST(LT, (set(&x, LH), x), OP, RT, RH, ID)) \
|
||||
x = -!(RS); \
|
||||
y = (LT)(set(&x, ID), LH) OP (RT)(set(&y, RH), y); \
|
||||
TEST(ID, RS, TEST_LINE_LHS_EFFECT_WITH_CAST(LT, LH, OP, RT, (set(&y, RH), y), ID))
|
||||
|
||||
void set(int *p, int q)
|
||||
{
|
||||
*p = q;
|
||||
}
|
||||
|
||||
int twice(int a)
|
||||
{
|
||||
return a * 2;
|
||||
}
|
||||
|
||||
int (*twicep)(int) = twice;
|
||||
|
||||
void test_unary(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
TEST_UNARY(+, 42, 42, 1);
|
||||
TEST_UNARY(-, -42, 42, 2);
|
||||
TEST_UNARY(~, ~42, 42, 3);
|
||||
TEST_UNARY(!, 42, 0, 4);
|
||||
}
|
||||
|
||||
void test_binary_arithmetic(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
TEST_BINARY(41, +, 1, 42, 1)
|
||||
TEST_BINARY(42, +, 0, 42, 1)
|
||||
|
||||
TEST_BINARY(43, -, 1, 42, 2)
|
||||
TEST_BINARY(42, -, 0, 42, 2)
|
||||
|
||||
TEST_BINARY(6, *, 7, 42, 3)
|
||||
TEST_BINARY(42, *, 1, 42, 3)
|
||||
TEST_BINARY(-42, *, -1, 42, 3)
|
||||
|
||||
TEST_BINARY(126, /, 3, 42, 4)
|
||||
TEST_BINARY(42, /, 1, 42, 4)
|
||||
TEST_BINARY(-42, /, -1, 42, 4)
|
||||
|
||||
TEST_BINARY(85, %, 43, 42, 5)
|
||||
TEST_BINARY(10794, %, 256, 42, 5)
|
||||
|
||||
TEST_BINARY(84, >>, 1, 42, 6)
|
||||
TEST_BINARY(42, >>, 0, 42, 6)
|
||||
TEST_BINARY(10752, >>, 8, 42, 6)
|
||||
TEST_BINARY(21504, >>, 9, 42, 6)
|
||||
|
||||
TEST_BINARY(21, <<, 1, 42, 7)
|
||||
TEST_BINARY(42, <<, 0, 42, 7)
|
||||
TEST_BINARY(42, <<, 8, 10752, 7)
|
||||
|
||||
TEST_BINARY(59, &, 238, 42, 8)
|
||||
TEST_BINARY(42, &, 0, 0, 8)
|
||||
TEST_BINARY(42, &, -1, 42, 8)
|
||||
|
||||
TEST_BINARY(34, |, 10, 42, 9)
|
||||
TEST_BINARY(42, |, 0, 42, 9)
|
||||
TEST_BINARY(34, |, -1, -1, 9)
|
||||
|
||||
TEST_BINARY(59, ^, 17, 42, 10)
|
||||
TEST_BINARY(42, ^, 0, 42, 10)
|
||||
TEST_BINARY(~42, ^, -1, 42, 10)
|
||||
}
|
||||
|
||||
void test_binary_comparison(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
TEST_BINARY(42, ==, 42, 1, 11)
|
||||
|
||||
TEST_BINARY(42, !=, 43, 1, 12)
|
||||
TEST_BINARY_WITH_CAST(signed char, 42, !=, long, 65536L, 1, 12)
|
||||
TEST_BINARY_WITH_CAST(long, 65536L, !=, signed char, 42, 1, 12)
|
||||
|
||||
TEST_BINARY(42, >, 41, 1, 13)
|
||||
TEST_BINARY_WITH_CAST(int, 0, >, unsigned, 42, 0, 13)
|
||||
|
||||
TEST_BINARY(42, <, 43, 1, 14)
|
||||
TEST_BINARY_WITH_CAST(unsigned, 42, <, int, 0, 0, 14)
|
||||
|
||||
TEST_BINARY(42, >=, 0, 1, 15)
|
||||
TEST_BINARY_WITH_CAST(unsigned, 42, >=, int, 0, 1, 15)
|
||||
|
||||
TEST_BINARY(42, <=, 43, 1, 16)
|
||||
TEST_BINARY_WITH_CAST(int, 0, <=, unsigned, 42, 1, 16)
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_unary();
|
||||
test_binary_arithmetic();
|
||||
test_binary_comparison();
|
||||
|
||||
if (failures != 0) {
|
||||
printf("Failures: %d\n", failures);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
@@ -1,60 +1,60 @@
|
||||
/* Tests for predefined macro __COUNTER__ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
|
||||
#if __COUNTER__ /* 0 */
|
||||
# error __COUNTER__ should begin at 0!
|
||||
#elif __COUNTER__ == 1 /* 1 */
|
||||
# define CONCAT(a,b) CONCAT_impl_(a,b)
|
||||
# define CONCAT_impl_(a,b) a##b
|
||||
#endif
|
||||
|
||||
#line 42 "What is the answer?"
|
||||
int CONCAT(ident,__COUNTER__)[0+__LINE__] = {__LINE__}, CONCAT(ident,__COUNTER__)[0+__LINE__] = {__LINE__}; /* 2,3 */
|
||||
|
||||
#if __COUNTER__ == 4 ? 1 || __COUNTER__ : 0 && __COUNTER__ /* 4,5,6 */
|
||||
_Static_assert(__COUNTER__ == 7, "__COUNTER__ should be 7 here!"); /* 7 */
|
||||
# define GET_COUNTER() __COUNTER__
|
||||
# define GET_LINE() __LINE__
|
||||
# warning __COUNTER__ in #warning is just output as text and will never increase!
|
||||
#else
|
||||
# if __COUNTER__ + __COUNTER__ + __COUNTER__ /* Skipped as a whole and not incrementing */
|
||||
# endif
|
||||
# error __COUNTER__ is skipped along with the whole #error line and will never increase anyways! */
|
||||
#endif
|
||||
|
||||
#include "counter.h"
|
||||
#include "counter.h"
|
||||
|
||||
_Static_assert(GET_COUNTER() == 10, "__COUNTER__ should be 10 here!"); /* 10 */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (ident2[0] != 42) {
|
||||
printf("Expected ident2[0]: %s, got: %s\n", 42, ident2[0]);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (ident3[0] != 42) {
|
||||
printf("Expected ident3[0]: %s, got: %s\n", 42, ident3[0]);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (ident8 != 8) {
|
||||
printf("Expected ident8: %s, got: %s\n", 8, ident8);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (ident9 != 9) {
|
||||
printf("Expected ident9: %s, got: %s\n", 9, ident9);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (failures != 0) {
|
||||
printf("Failures: %d\n", failures);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
/* Tests for predefined macro __COUNTER__ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int failures = 0;
|
||||
|
||||
#if __COUNTER__ /* 0 */
|
||||
# error __COUNTER__ should begin at 0!
|
||||
#elif __COUNTER__ == 1 /* 1 */
|
||||
# define CONCAT(a,b) CONCAT_impl_(a,b)
|
||||
# define CONCAT_impl_(a,b) a##b
|
||||
#endif
|
||||
|
||||
#line 42 "What is the answer?"
|
||||
int CONCAT(ident,__COUNTER__)[0+__LINE__] = {__LINE__}, CONCAT(ident,__COUNTER__)[0+__LINE__] = {__LINE__}; /* 2,3 */
|
||||
|
||||
#if __COUNTER__ == 4 ? 1 || __COUNTER__ : 0 && __COUNTER__ /* 4,5,6 */
|
||||
_Static_assert(__COUNTER__ == 7, "__COUNTER__ should be 7 here!"); /* 7 */
|
||||
# define GET_COUNTER() __COUNTER__
|
||||
# define GET_LINE() __LINE__
|
||||
# warning __COUNTER__ in #warning is just output as text and will never increase!
|
||||
#else
|
||||
# if __COUNTER__ + __COUNTER__ + __COUNTER__ /* Skipped as a whole and not incrementing */
|
||||
# endif
|
||||
# error __COUNTER__ is skipped along with the whole #error line and will never increase anyways! */
|
||||
#endif
|
||||
|
||||
#include "counter.h"
|
||||
#include "counter.h"
|
||||
|
||||
_Static_assert(GET_COUNTER() == 10, "__COUNTER__ should be 10 here!"); /* 10 */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (ident2[0] != 42) {
|
||||
printf("Expected ident2[0]: %s, got: %s\n", 42, ident2[0]);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (ident3[0] != 42) {
|
||||
printf("Expected ident3[0]: %s, got: %s\n", 42, ident3[0]);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (ident8 != 8) {
|
||||
printf("Expected ident8: %s, got: %s\n", 8, ident8);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (ident9 != 9) {
|
||||
printf("Expected ident9: %s, got: %s\n", 9, ident9);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (failures != 0) {
|
||||
printf("Failures: %d\n", failures);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Tests for predefined macro __COUNTER__ */
|
||||
|
||||
#line GET_COUNTER() /* 1st: 8; 2nd: 9 */
|
||||
int CONCAT(ident,GET_LINE()) = GET_LINE();
|
||||
/* Tests for predefined macro __COUNTER__ */
|
||||
|
||||
#line GET_COUNTER() /* 1st: 8; 2nd: 9 */
|
||||
int CONCAT(ident,GET_LINE()) = GET_LINE();
|
||||
|
||||
31
test/val/decl-extern-shadow.c
Normal file
31
test/val/decl-extern-shadow.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* Test for shadowing and linkage of file-scope "static" and block-scope "extern" declarations */
|
||||
|
||||
static int g(int x); /* Generated functions with internal linkage are not always kept in cc65 */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char f = 'f'; /* Shadows global "int f(void)" (if any) */
|
||||
char c = 'c'; /* Shadows global "int c" (if any) */
|
||||
{
|
||||
void* f = 0; /* Shadows local "char f" */
|
||||
void* c = 0; /* Shadows local "char c" */
|
||||
{
|
||||
int f(void); /* Shadows local "char f" and "void* f" */
|
||||
extern int g(int); /* Shadows global "int g(int x)" */
|
||||
extern int c; /* Shadows local "char c" and "void* c" */
|
||||
return f() ^ g(c); /* Link to global "int g(int x)" */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int c = 42;
|
||||
|
||||
int f(void)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
int g(int x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
19
test/val/decl-mixed-specifiers.c
Normal file
19
test/val/decl-mixed-specifiers.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* bug 1888 - cc65 fails with storage class specifiers after type specifiers */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int const typedef volatile x_type, * const volatile y_type;
|
||||
|
||||
int static failures = 0;
|
||||
|
||||
int extern main(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
volatile static x_type const x = 42, * const volatile y[] = { 1 ? &x : (y_type)0 };
|
||||
if (**y != 42) {
|
||||
++failures;
|
||||
printf("y = %d, Expected: 42\n", **y);
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
@@ -26,15 +26,17 @@ void done()
|
||||
|
||||
void m1(void)
|
||||
{
|
||||
c1 = c1*5; /* char = char * lit */
|
||||
c1 = c1*5; /* char = char * lit */
|
||||
c2 = c1*c3; /* char = char * char */
|
||||
|
||||
c2 = c1 *c3; /* char = char * char */
|
||||
|
||||
uc1= uc1*5; /* uchar = uchar * lit *
|
||||
uc2=uc1*uc3; /* uchar = uchar * uchar */
|
||||
uc1 = uc1*3; /* uchar = uchar * lit */
|
||||
uc2 = uc1*uc3; /* uchar = uchar * uchar */
|
||||
|
||||
if(c2 != 25)
|
||||
failures++;
|
||||
|
||||
if(uc2 != 36)
|
||||
failures++;
|
||||
}
|
||||
|
||||
void m2(unsigned char uc)
|
||||
@@ -96,6 +98,9 @@ int main(void)
|
||||
c1 = 1;
|
||||
c3 = 5;
|
||||
|
||||
uc1 = 2;
|
||||
uc3 = 6;
|
||||
|
||||
m1();
|
||||
|
||||
uc1 = 0x10;
|
||||
@@ -107,7 +112,7 @@ int main(void)
|
||||
|
||||
ui3 = ui1*ui2; /* uint = uint * unit */
|
||||
|
||||
/*m3(TESTLIT);*/
|
||||
m3(TESTLIT);
|
||||
|
||||
success = failures;
|
||||
done();
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
|
||||
/* Test for result types of certain unary operations */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
signed char x;
|
||||
struct S {
|
||||
unsigned char a : 3;
|
||||
unsigned int b : 3;
|
||||
} s;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
_Static_assert(sizeof (++x) == sizeof (char), "++x result should not have promoted type");
|
||||
_Static_assert(sizeof (--x) == sizeof (char), "--x result should not have promoted type");
|
||||
_Static_assert(sizeof (x++) == sizeof (char), "x++ result should not have promoted type");
|
||||
_Static_assert(sizeof (x--) == sizeof (char), "x-- result should not have promoted type");
|
||||
_Static_assert(sizeof (x=0) == sizeof (char), "x=0 result should not have promoted type");
|
||||
|
||||
_Static_assert(sizeof (+x) == sizeof (int), "+x result should have promoted type");
|
||||
_Static_assert(sizeof (-x) == sizeof (int), "-x result should have promoted type");
|
||||
_Static_assert(sizeof (~x) == sizeof (int), "~x result should have promoted type");
|
||||
|
||||
_Static_assert(sizeof (+s.a) == sizeof (int), "+s.a result should have promoted type");
|
||||
_Static_assert(sizeof (-s.a) == sizeof (int), "-s.a result should have promoted type");
|
||||
_Static_assert(sizeof (~s.a) == sizeof (int), "~s.a result should have promoted type");
|
||||
|
||||
_Static_assert(sizeof (+s.b) == sizeof (int), "+s.b result should have promoted type");
|
||||
_Static_assert(sizeof (-s.b) == sizeof (int), "-s.b result should have promoted type");
|
||||
_Static_assert(sizeof (~s.b) == sizeof (int), "~s.b result should have promoted type");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test for result types of certain unary operations */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
signed char x;
|
||||
struct S {
|
||||
unsigned char a : 3;
|
||||
unsigned int b : 3;
|
||||
} s;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
_Static_assert(sizeof (++x) == sizeof (char), "++x result should not have promoted type");
|
||||
_Static_assert(sizeof (--x) == sizeof (char), "--x result should not have promoted type");
|
||||
_Static_assert(sizeof (x++) == sizeof (char), "x++ result should not have promoted type");
|
||||
_Static_assert(sizeof (x--) == sizeof (char), "x-- result should not have promoted type");
|
||||
_Static_assert(sizeof (x=0) == sizeof (char), "x=0 result should not have promoted type");
|
||||
|
||||
_Static_assert(sizeof (+x) == sizeof (int), "+x result should have promoted type");
|
||||
_Static_assert(sizeof (-x) == sizeof (int), "-x result should have promoted type");
|
||||
_Static_assert(sizeof (~x) == sizeof (int), "~x result should have promoted type");
|
||||
|
||||
_Static_assert(sizeof (+s.a) == sizeof (int), "+s.a result should have promoted type");
|
||||
_Static_assert(sizeof (-s.a) == sizeof (int), "-s.a result should have promoted type");
|
||||
_Static_assert(sizeof (~s.a) == sizeof (int), "~s.a result should have promoted type");
|
||||
|
||||
_Static_assert(sizeof (+s.b) == sizeof (int), "+s.b result should have promoted type");
|
||||
_Static_assert(sizeof (-s.b) == sizeof (int), "-s.b result should have promoted type");
|
||||
_Static_assert(sizeof (~s.b) == sizeof (int), "~s.b result should have promoted type");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
120
test/val/ppshift.c
Normal file
120
test/val/ppshift.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Test of bitwise-shift in preprocessor expressions.
|
||||
|
||||
Note: Keep in mind that integer constants are always 32-bit in PP for cc65.
|
||||
*/
|
||||
|
||||
/* Signed lhs */
|
||||
#if 1 << 16 != 0x00010000
|
||||
#error 1 << 16 != 0x00010000
|
||||
#endif
|
||||
|
||||
#if 0x00010000 << -16 != 1
|
||||
#error 0x00010000 << -16 != 1
|
||||
#endif
|
||||
|
||||
#if 0x10000 >> 16 != 1
|
||||
#error 0x10000 >> 16 != 1
|
||||
#endif
|
||||
|
||||
#if 1 >> -16 != 0x10000
|
||||
#error 1 >> -16 != 0x10000
|
||||
#endif
|
||||
|
||||
#if 1 << 32 != 0
|
||||
#error 1 << 32 != 0
|
||||
#endif
|
||||
|
||||
#if 1 << -32 != 0
|
||||
#error 1 << -32 != 0
|
||||
#endif
|
||||
|
||||
#if 1 >> 32 != 0
|
||||
#error 1 >> 32 != 0
|
||||
#endif
|
||||
|
||||
#if 1 >> -32 != 0
|
||||
#error 1 >> -32 != 0
|
||||
#endif
|
||||
|
||||
#if -1 << 32 != 0
|
||||
#error -1 << 32 != 0
|
||||
#endif
|
||||
|
||||
#if -1 << -32 != -1
|
||||
#error -1 << -32 != -1
|
||||
#endif
|
||||
|
||||
#if -1 >> 32 != -1
|
||||
#error -1 >> 32 != -1
|
||||
#endif
|
||||
|
||||
#if -1 >> -32 != 0
|
||||
#error -1 >> -32 != 0
|
||||
#endif
|
||||
|
||||
/* NOTE: 2147483648 is an UNSIGNED integer! */
|
||||
#if -1 << 2147483648 != 0
|
||||
#error -1 << 2147483648 != 0
|
||||
#endif
|
||||
|
||||
/* NOTE: -2147483648 is also an UNSIGNED integer! */
|
||||
#if -1 << -2147483648 != 0
|
||||
#error -1 << -2147483648 != 0
|
||||
#endif
|
||||
|
||||
#if -1 << (-2147483647 - 1) != -1
|
||||
#error -1 << (-2147483647 - 1) != -1
|
||||
#endif
|
||||
|
||||
/* NOTE: 2147483648 is an UNSIGNED integer! */
|
||||
#if -1 >> 2147483648 != -1
|
||||
#error -1 >> 2147483648 != -1
|
||||
#endif
|
||||
|
||||
/* NOTE: -2147483648 is also an UNSIGNED integer! */
|
||||
#if -1 >> -2147483648 != -1
|
||||
#error -1 >> -2147483648 != 0
|
||||
#endif
|
||||
|
||||
#if -1 >> (-2147483647 - 1) != 0
|
||||
#error -1 >> (-2147483647 - 1) != 0
|
||||
#endif
|
||||
|
||||
/* Unsigned lhs */
|
||||
#if 1U << 16 != 0x00010000
|
||||
#error 1U << 16 != 0x00010000
|
||||
#endif
|
||||
|
||||
#if 0x80000000U << -16 != 0x8000
|
||||
#error 0x80000000U << -16 != 0x8000
|
||||
#endif
|
||||
|
||||
#if 0x80000000U >> 16 != 0x8000
|
||||
#error 0x80000000U >> 16 != 0x8000
|
||||
#endif
|
||||
|
||||
#if 1U >> -16 != 0x10000
|
||||
#error 1U >> -16 != 0x10000
|
||||
#endif
|
||||
|
||||
#if -1U << 32 != 0
|
||||
#error -1U << 32 != 0
|
||||
#endif
|
||||
|
||||
#if -1U << -32 != 0
|
||||
#error -1U << -32 != 0
|
||||
#endif
|
||||
|
||||
#if -1U >> 32 != 0
|
||||
#error -1U >> 32 != 0
|
||||
#endif
|
||||
|
||||
#if -1U >> -32 != 0
|
||||
#error -1U >> -32 != 0
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
/* Test for PR #1833 fixes */
|
||||
|
||||
#define char 1
|
||||
|
||||
#if char && !int && L'A' - L'B' == 'A' - 'B' && L'A' == 'A'
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Test for PR #1833 fixes */
|
||||
|
||||
#define char 1
|
||||
|
||||
#if char && !int && L'A' - L'B' == 'A' - 'B' && L'A' == 'A'
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,13 @@ struct S {
|
||||
int b;
|
||||
};
|
||||
|
||||
/* _Static_assert can also appear in unions. */
|
||||
union U {
|
||||
int a;
|
||||
_Static_assert (1, "1 should still be true.");
|
||||
int b;
|
||||
};
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user