aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--.gitignore24
-rw-r--r--ast-inspect.c2
-rwxr-xr-xcgcc68
-rw-r--r--evaluate.c8
-rw-r--r--gdbhelpers3
-rw-r--r--lib.c182
-rw-r--r--lib.h15
-rw-r--r--machine.h22
-rw-r--r--parse.c8
-rw-r--r--show-parse.c3
-rw-r--r--sparse.18
-rw-r--r--symbol.c4
-rw-r--r--symbol.h8
-rw-r--r--target.c22
-rw-r--r--validation/arch/arm.c27
-rw-r--r--validation/arch/arm64.c23
-rw-r--r--validation/arch/mips32.c29
-rw-r--r--validation/arch/riscv64.c27
18 files changed, 384 insertions, 99 deletions
diff --git a/.gitignore b/.gitignore
index da103de8..91305a6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,31 +1,31 @@
# generic
+*.a
*.o
*.o.d
-*.a
-*.so
-.*.swp
*.pyc
+*.so
*~
+.*.swp
# generated
version.h
# programs
-test-inspect
-test-lexing
-test-parsing
-obfuscate
-sparse
+c2xml
compile
+ctags
+example
graph
+obfuscate
+sparse
+sparse-llvm
test-dissect
+test-inspect
+test-lexing
test-linearize
+test-parsing
test-show-type
-example
test-unssa
-ctags
-c2xml
-sparse-llvm
# tags
tags
diff --git a/ast-inspect.c b/ast-inspect.c
index 24d4a4a6..b510cd9b 100644
--- a/ast-inspect.c
+++ b/ast-inspect.c
@@ -109,9 +109,7 @@ static const char *symbol_type_name(enum type type)
[SYM_STRUCT] = "SYM_STRUCT",
[SYM_UNION] = "SYM_UNION",
[SYM_ENUM] = "SYM_ENUM",
- [SYM_TYPEDEF] = "SYM_TYPEDEF",
[SYM_TYPEOF] = "SYM_TYPEOF",
- [SYM_MEMBER] = "SYM_MEMBER",
[SYM_BITFIELD] = "SYM_BITFIELD",
[SYM_LABEL] = "SYM_LABEL",
[SYM_RESTRICT] = "SYM_RESTRICT",
diff --git a/cgcc b/cgcc
index 122f6e27..93bdc644 100755
--- a/cgcc
+++ b/cgcc
@@ -148,30 +148,6 @@ sub quote_arg {
# -----------------------------------------------------------------------------
-sub integer_types {
- my ($char,@dummy) = @_;
-
- my %pow2m1 =
- (8 => '127',
- 16 => '32767',
- 32 => '2147483647',
- 64 => '9223372036854775807',
- 128 => '170141183460469231731687303715884105727',
- );
- my @types = (['SCHAR',''], ['SHRT',''], ['INT',''], ['LONG','L'], ['LONG_LONG','LL'], ['LONG_LONG_LONG','LLL']);
-
- my $result = " -D__CHAR_BIT__=$char";
- while (@types && @_) {
- my $bits = shift @_;
- my ($name,$suffix) = @{ shift @types };
- die "$0: weird number of bits." unless exists $pow2m1{$bits};
- $result .= " -D__${name}_MAX__=" . $pow2m1{$bits} . $suffix;
- }
- return $result;
-}
-
-# -----------------------------------------------------------------------------
-
sub float_types {
my ($has_inf,$has_qnan,$dec_dig,@bitsizes) = @_;
my $result = " -D__FLT_RADIX__=2";
@@ -241,14 +217,6 @@ sub float_types {
# -----------------------------------------------------------------------------
-sub define_size_t {
- my ($text) = @_;
- # We have to undef in order to override check's internal definition.
- return ' -U__SIZE_TYPE__ ' . &quote_arg ("-D__SIZE_TYPE__=$text");
-}
-
-# -----------------------------------------------------------------------------
-
sub add_specs {
my ($spec) = @_;
if ($spec eq 'sunos') {
@@ -294,29 +262,25 @@ sub add_specs {
" -D'__declspec(x)=__attribute__((x))'";
} elsif ($spec eq 'i386') {
return (
+ ' --arch=i386' .
&float_types (1, 1, 21, [24,8], [53,11], [64,15]));
} elsif ($spec eq 'sparc') {
return (
- &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) .
- &float_types (1, 1, 33, [24,8], [53,11], [113,15]) .
- &define_size_t ($m64 ? "long unsigned int" : "unsigned int") .
- ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4'));
+ ' --arch=sparc' .
+ &float_types (1, 1, 33, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'sparc64') {
return (
- &integer_types (8, 16, 32, 64, 64, 128) .
- &float_types (1, 1, 33, [24,8], [53,11], [113,15]) .
- &define_size_t ("long unsigned int") .
- ' -D__SIZEOF_POINTER__=8');
+ ' --arch=sparc64' .
+ &float_types (1, 1, 33, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'x86_64') {
- return &float_types (1, 1, 33, [24,8], [53,11], [113,15]);
+ return (' --arch=x86_64' .
+ &float_types (1, 1, 33, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'ppc') {
- return (' -D_BIG_ENDIAN -D_STRING_ARCH_unaligned=1' .
- &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) .
- &float_types (1, 1, 21, [24,8], [53,11], [113,15]) .
- &define_size_t ($m64 ? "long unsigned int" : "unsigned int") .
- ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4'));
+ return (' --arch=ppc' .
+ &float_types (1, 1, 21, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'ppc64') {
- return (' -D_STRING_ARCH_unaligned=1 -m64' .
+ return (
+ ' --arch=ppc64' .
&float_types (1, 1, 21, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'ppc64+be') {
return &add_specs ('ppc64') . ' -mbig-endian -D_CALL_ELF=1';
@@ -324,17 +288,15 @@ sub add_specs {
return &add_specs ('ppc64') . ' -mlittle-endian -D_CALL_ELF=2';
} elsif ($spec eq 's390x') {
return (' -D_BIG_ENDIAN' .
- &integer_types (8, 16, 32, $m64 ? 64 : 32, 64) .
- &float_types (1, 1, 36, [24,8], [53,11], [113,15]) .
- &define_size_t ("long unsigned int") .
- ' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4'));
+ ' --arch=s390x' .
+ &float_types (1, 1, 36, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'arm') {
- return (' -m32' .
+ return (' --arch=arm' .
&float_types (1, 1, 36, [24,8], [53,11], [53, 11]));
} elsif ($spec eq 'arm+hf') {
return &add_specs ('arm') . ' -D__ARM_PCS_VFP=1';
} elsif ($spec eq 'aarch64') {
- return (' -m64' .
+ return (' --arch=aarch64' .
&float_types (1, 1, 36, [24,8], [53,11], [113,15]));
} elsif ($spec eq 'host_os_specs') {
my $os = `uname -s`;
diff --git a/evaluate.c b/evaluate.c
index 74c7fd1d..7c3389cf 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1096,11 +1096,11 @@ static struct symbol *evaluate_compare(struct expression *expr)
goto OK;
}
if (is_null1 && (rclass & TYPE_PTR)) {
- left = cast_to(left, rtype);
+ expr->left = cast_to(left, rtype);
goto OK;
}
if (is_null2 && (lclass & TYPE_PTR)) {
- right = cast_to(right, ltype);
+ expr->right = cast_to(right, ltype);
goto OK;
}
}
@@ -1116,11 +1116,11 @@ static struct symbol *evaluate_compare(struct expression *expr)
if (expr->op == SPECIAL_EQUAL || expr->op == SPECIAL_NOTEQUAL) {
if (ltype->ctype.as == rtype->ctype.as) {
if (lbase == &void_ctype) {
- right = cast_to(right, ltype);
+ expr->right = cast_to(right, ltype);
goto OK;
}
if (rbase == &void_ctype) {
- left = cast_to(left, rtype);
+ expr->left = cast_to(left, rtype);
goto OK;
}
}
diff --git a/gdbhelpers b/gdbhelpers
index 2fe9336d..8d186cee 100644
--- a/gdbhelpers
+++ b/gdbhelpers
@@ -152,9 +152,6 @@ define gdb_show_ctype
if ($arg0->modifiers & MOD_ASSIGNED)
printf "MOD_ASSIGNED "
end
- if ($arg0->modifiers & MOD_TYPE)
- printf "MOD_TYPE "
- end
if ($arg0->modifiers & MOD_SAFE)
printf "MOD_SAFE "
end
diff --git a/lib.c b/lib.c
index 75a4f987..fd45da5d 100644
--- a/lib.c
+++ b/lib.c
@@ -310,6 +310,8 @@ unsigned long fdump_ir;
int fmem_report = 0;
unsigned long long fmemcpy_max_count = 100000;
unsigned long fpasses = ~0UL;
+int fpic = 0;
+int fpie = 0;
int funsigned_char = UNSIGNED_CHAR;
int preprocess_only;
@@ -326,6 +328,7 @@ static int arch_msize_long = 0;
int arch_m64 = ARCH_M64_DEFAULT;
int arch_big_endian = ARCH_BIG_ENDIAN;
int arch_mach = MACH_NATIVE;
+int arch_cmodel = CMODEL_UNKNOWN;
#define CMDLINE_INCLUDE 20
@@ -456,6 +459,8 @@ static char **handle_switch_m(char *arg, char **next)
arch_m64 = ARCH_LP64;
} else if (!strcmp(arg, "m32") || !strcmp(arg, "m16")) {
arch_m64 = ARCH_LP32;
+ } else if (!strcmp(arg, "m31")) {
+ arch_m64 = ARCH_LP32;
} else if (!strcmp(arg, "mx32")) {
arch_m64 = ARCH_X32;
} else if (!strcmp(arg, "msize-llp64")) {
@@ -468,6 +473,26 @@ static char **handle_switch_m(char *arg, char **next)
arch_big_endian = 1;
} else if (!strcmp(arg, "mlittle-endian")) {
arch_big_endian = 0;
+ } else if (!strncmp(arg, "mcmodel", 7)) {
+ arg += 7;
+ if (*arg++ != '=')
+ die("missing argument for -mcmodel");
+ else if (!strcmp(arg, "kernel"))
+ arch_cmodel = CMODEL_KERNEL;
+ else if (!strcmp(arg, "large"))
+ arch_cmodel = CMODEL_LARGE;
+ else if (!strcmp(arg, "medany"))
+ arch_cmodel = CMODEL_MEDANY;
+ else if (!strcmp(arg, "medium"))
+ arch_cmodel = CMODEL_MEDIUM;
+ else if (!strcmp(arg, "medlow"))
+ arch_cmodel = CMODEL_MEDLOW;
+ else if (!strcmp(arg, "small"))
+ arch_cmodel = CMODEL_SMALL;
+ else if (!strcmp(arg, "tiny"))
+ arch_cmodel = CMODEL_TINY;
+ else
+ die("invalid argument for -mcmodel=%s", arg);
}
return next;
}
@@ -483,6 +508,23 @@ static void handle_arch_msize_long_finalize(void)
static void handle_arch_finalize(void)
{
handle_arch_msize_long_finalize();
+
+ if (fpie > fpic)
+ fpic = fpie;
+
+ switch (arch_mach) {
+ case MACH_ARM64:
+ if (arch_cmodel == CMODEL_UNKNOWN)
+ arch_cmodel = CMODEL_SMALL;
+ break;
+ case MACH_RISCV32:
+ case MACH_RISCV64:
+ if (arch_cmodel == CMODEL_UNKNOWN)
+ arch_cmodel = CMODEL_MEDLOW;
+ if (fpic)
+ arch_cmodel = CMODEL_PIC;
+ break;
+ }
}
static const char *match_option(const char *arg, const char *prefix)
@@ -592,6 +634,12 @@ static int handle_switches(const char *ori, const char *opt, const struct flag *
return 0;
}
+static int handle_switch_setval(const char *arg, const char *opt, const struct flag *flag, int options)
+{
+ *(flag->flag) = flag->mask;
+ return 1;
+}
+
#define OPTNUM_ZERO_IS_INF 1
#define OPTNUM_UNLIMITED 2
@@ -940,6 +988,10 @@ static struct flag fflags[] = {
{ "tabstop=", NULL, handle_ftabstop },
{ "mem2reg", NULL, handle_fpasses, PASS_MEM2REG },
{ "optim", NULL, handle_fpasses, PASS_OPTIM },
+ { "pic", &fpic, handle_switch_setval, 1 },
+ { "PIC", &fpic, handle_switch_setval, 2 },
+ { "pie", &fpie, handle_switch_setval, 1 },
+ { "PIE", &fpie, handle_switch_setval, 2 },
{ "signed-char", &funsigned_char, NULL, OPT_INVERSE },
{ "unsigned-char", &funsigned_char, NULL, },
{ },
@@ -1044,6 +1096,71 @@ static char **handle_switch_x(char *arg, char **next)
}
+static char **handle_arch(char *arg, char **next)
+{
+ static const struct arch {
+ const char *name;
+ char mach;
+ char bits;
+ bool big_endian:1;
+ } archs[] = {
+ { "aarch64", MACH_ARM64, 64, 0 },
+ { "arm64", MACH_ARM64, 64, 0 },
+ { "arm", MACH_ARM, 32, 0 },
+ { "i386", MACH_I386, 32, 0 },
+ { "m68k", MACH_M68K, 32, 0 },
+ { "mips", MACH_MIPS32, 0, 1 },
+ { "powerpc", MACH_PPC32, 0, 1 },
+ { "ppc", MACH_PPC32, 0, 1 },
+ { "riscv", MACH_RISCV32, 0, 0 },
+ { "s390x", MACH_S390X, 64, 1 },
+ { "s390", MACH_S390, 32, 1 },
+ { "sparc", MACH_SPARC32, 0, 1 },
+ { "x86_64", MACH_X86_64, 64, 0 },
+ { "x86-64", MACH_X86_64, 64, 0 },
+ { NULL },
+ };
+ const struct arch *p;
+
+ if (*arg++ != '=')
+ die("missing argument for --arch option");
+
+ for (p = &archs[0]; p->name; p++) {
+ size_t len = strlen(p->name);
+ if (strncmp(p->name, arg, len) == 0) {
+ const char *suf = arg + len;
+ int bits = p->bits;
+
+ arch_mach = p->mach;
+ if (bits == 0) {
+ if (!strcmp(suf, "")) {
+ bits = 32;
+ } else if (!strcmp(suf, "32")) {
+ bits = 32;
+ } else if (!strcmp(suf, "64")) {
+ bits = 64;
+ arch_mach += 1;
+ } else {
+ die("invalid architecture: %s", arg);
+ }
+ } else {
+ if (strcmp(suf, ""))
+ die("invalid architecture: %s", arg);
+ }
+
+ // adjust the arch size (but keep x32 & llp64)
+ if (bits == 32)
+ arch_m64 = ARCH_LP32;
+ else if (bits == 64 && arch_m64 == ARCH_LP32)
+ arch_m64 = ARCH_LP64;
+ arch_big_endian = p->big_endian;
+ break;
+ }
+ }
+
+ return next;
+}
+
static char **handle_version(char *arg, char **next)
{
printf("%s\n", SPARSE_VERSION);
@@ -1076,6 +1193,7 @@ struct switches {
static char **handle_long_options(char *arg, char **next)
{
static struct switches cmd[] = {
+ { "arch", handle_arch, 1 },
{ "param", handle_param, 1 },
{ "version", handle_version },
{ NULL, NULL }
@@ -1198,6 +1316,55 @@ static void predefined_ctype(const char *name, struct symbol *type, int flags)
predefined_width(name, bits);
}
+static void predefined_cmodel(void)
+{
+ const char *pre, *suf;
+ const char *def = NULL;
+ switch (arch_mach) {
+ case MACH_ARM64:
+ pre = "__AARCH64_CMODEL_";
+ suf = "__";
+ switch (arch_cmodel) {
+ case CMODEL_LARGE:
+ def = "LARGE";
+ break;
+ case CMODEL_SMALL:
+ def = "SMALL";
+ break;
+ case CMODEL_TINY:
+ def = "TINY";
+ break;
+ default:
+ break;
+ }
+ break;
+ case MACH_RISCV32:
+ case MACH_RISCV64:
+ pre = "__riscv_cmodel_";
+ suf = "";
+ switch (arch_cmodel) {
+ case CMODEL_MEDLOW:
+ def = "medlow";
+ break;
+ case CMODEL_MEDANY:
+ def = "medany";
+ break;
+ case CMODEL_PIC:
+ def = "pic";
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!def)
+ return;
+ add_pre_buffer("#weak_define %s%s%s 1\n", pre, def, suf);
+}
+
static void predefined_macros(void)
{
predefine("__CHECKER__", 0, "1");
@@ -1329,6 +1496,7 @@ static void predefined_macros(void)
predefine("__mips64", 1, "64");
/* fall-through */
case MACH_MIPS32:
+ predefine("__mips__", 1, "1");
predefine("__mips", 1, "%d", ptr_ctype.bit_size);
predefine("_MIPS_SZINT", 1, "%d", int_ctype.bit_size);
predefine("_MIPS_SZLONG", 1, "%d", long_ctype.bit_size);
@@ -1346,6 +1514,8 @@ static void predefined_macros(void)
predefine("__powerpc", 1, "1");
predefine("__ppc__", 1, "1");
predefine("__PPC__", 1, "1");
+ if (arch_big_endian)
+ predefine("_BIG_DEBIAN", 1, "1");
break;
case MACH_RISCV64:
case MACH_RISCV32:
@@ -1355,6 +1525,7 @@ static void predefined_macros(void)
case MACH_S390X:
predefine("__zarch__", 1, "1");
predefine("__s390x__", 1, "1");
+ case MACH_S390:
predefine("__s390__", 1, "1");
break;
case MACH_SPARC64:
@@ -1382,6 +1553,17 @@ static void predefined_macros(void)
predefine("__i386", 1, "1");
break;
}
+
+ if (fpic) {
+ predefine("__pic__", 0, "%d", fpic);
+ predefine("__PIC__", 0, "%d", fpic);
+ }
+ if (fpie) {
+ predefine("__pie__", 0, "%d", fpie);
+ predefine("__PIE__", 0, "%d", fpie);
+ }
+
+ predefined_cmodel();
}
static void create_builtin_stream(void)
diff --git a/lib.h b/lib.h
index 18c97b4f..f6dea8ca 100644
--- a/lib.h
+++ b/lib.h
@@ -199,12 +199,27 @@ extern int fmem_report;
extern unsigned long fdump_ir;
extern unsigned long long fmemcpy_max_count;
extern unsigned long fpasses;
+extern int fpic;
+extern int fpie;
extern int funsigned_char;
extern int arch_m64;
extern int arch_big_endian;
extern int arch_mach;
+enum {
+ CMODEL_UNKNOWN,
+ CMODEL_KERNEL,
+ CMODEL_LARGE,
+ CMODEL_MEDANY,
+ CMODEL_MEDIUM,
+ CMODEL_MEDLOW,
+ CMODEL_PIC,
+ CMODEL_SMALL,
+ CMODEL_TINY,
+};
+extern int arch_cmodel;
+
extern void dump_macro_definitions(void);
extern struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **files);
extern struct symbol_list *__sparse(char *filename);
diff --git a/machine.h b/machine.h
index b46383ac..e24822a7 100644
--- a/machine.h
+++ b/machine.h
@@ -25,20 +25,14 @@ enum {
enum machine {
- MACH_ARM,
- MACH_ARM64,
- MACH_I386,
- MACH_X86_64,
- MACH_MIPS32,
- MACH_MIPS64,
- MACH_PPC32,
- MACH_PPC64,
- MACH_RISCV32,
- MACH_RISCV64,
- MACH_SPARC32,
- MACH_SPARC64,
+ MACH_ARM, MACH_ARM64,
+ MACH_I386, MACH_X86_64,
+ MACH_MIPS32, MACH_MIPS64,
+ MACH_PPC32, MACH_PPC64,
+ MACH_RISCV32, MACH_RISCV64,
+ MACH_SPARC32, MACH_SPARC64,
+ MACH_S390, MACH_S390X,
MACH_M68K,
- MACH_S390X,
MACH_UNKNOWN
};
@@ -70,6 +64,8 @@ enum machine {
#define MACH_NATIVE MACH_M68K
#elif defined(__s390x__) || defined(__zarch__)
#define MACH_NATIVE MACH_S390X
+#elif defined(__s390__)
+#define MACH_NATIVE MACH_S390
#else
#define MACH_NATIVE MACH_UNKNOWN
#endif
diff --git a/parse.c b/parse.c
index 48a63f22..4b0a1566 100644
--- a/parse.c
+++ b/parse.c
@@ -345,6 +345,7 @@ static struct symbol_op goto_op = {
static struct symbol_op __context___op = {
.statement = parse_context_statement,
+ .attribute = attribute_context,
};
static struct symbol_op range_op = {
@@ -537,6 +538,7 @@ static struct init_keyword {
{ "while", NS_KEYWORD, .op = &while_op },
{ "do", NS_KEYWORD, .op = &do_op },
{ "goto", NS_KEYWORD, .op = &goto_op },
+ { "context", NS_KEYWORD, .op = &context_op },
{ "__context__",NS_KEYWORD, .op = &__context___op },
{ "__range__", NS_KEYWORD, .op = &range_op },
{ "asm", NS_KEYWORD, .op = &asm_op },
@@ -549,13 +551,17 @@ static struct init_keyword {
{ "aligned", NS_KEYWORD, .op = &aligned_op },
{ "__aligned__",NS_KEYWORD, .op = &aligned_op },
{ "nocast", NS_KEYWORD, MOD_NOCAST, .op = &attr_mod_op },
+ { "__nocast__", NS_KEYWORD, MOD_NOCAST, .op = &attr_mod_op },
{ "noderef", NS_KEYWORD, MOD_NODEREF, .op = &attr_mod_op },
+ { "__noderef__",NS_KEYWORD, MOD_NODEREF, .op = &attr_mod_op },
{ "safe", NS_KEYWORD, MOD_SAFE, .op = &attr_mod_op },
+ { "__safe__", NS_KEYWORD, MOD_SAFE, .op = &attr_mod_op },
{ "force", NS_KEYWORD, .op = &attr_force_op },
+ { "__force__", NS_KEYWORD, .op = &attr_force_op },
{ "bitwise", NS_KEYWORD, MOD_BITWISE, .op = &attr_bitwise_op },
{ "__bitwise__",NS_KEYWORD, MOD_BITWISE, .op = &attr_bitwise_op },
{ "address_space",NS_KEYWORD, .op = &address_space_op },
- { "context", NS_KEYWORD, .op = &context_op },
+ { "__address_space__",NS_KEYWORD, .op = &address_space_op },
{ "designated_init", NS_KEYWORD, .op = &designated_init_op },
{ "__designated_init__", NS_KEYWORD, .op = &designated_init_op },
{ "transparent_union", NS_KEYWORD, .op = &transparent_union_op },
diff --git a/show-parse.c b/show-parse.c
index 80125e74..1c0ecf7e 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -58,9 +58,7 @@ static void do_debug_symbol(struct symbol *sym, int indent)
[SYM_STRUCT] = "strt",
[SYM_UNION] = "unin",
[SYM_ENUM] = "enum",
- [SYM_TYPEDEF] = "tdef",
[SYM_TYPEOF] = "tpof",
- [SYM_MEMBER] = "memb",
[SYM_BITFIELD] = "bitf",
[SYM_LABEL] = "labl",
[SYM_RESTRICT] = "rstr",
@@ -142,7 +140,6 @@ const char *modifier_string(unsigned long mod)
{MOD_NODEREF, "[noderef]"},
{MOD_TOPLEVEL, "[toplevel]"},
{MOD_ASSIGNED, "[assigned]"},
- {MOD_TYPE, "[type]"},
{MOD_SAFE, "[safe]"},
{MOD_USERTYPE, "[usertype]"},
{MOD_NORETURN, "[noreturn]"},
diff --git a/sparse.1 b/sparse.1
index beb48442..be38f688 100644
--- a/sparse.1
+++ b/sparse.1
@@ -423,6 +423,14 @@ Sparse does not issue these warnings by default.
.
.SH MISC OPTIONS
.TP
+.B \-\-arch=\fIARCH\fR
+Specify the target architecture.
+For architectures having both a 32-bit and a 64-bit variant (mips, powerpc,
+riscv & sparc) the architecture name can be suffixed with \fI32\fR or \fI64\fR.
+
+The default architecture & size is the one of the machine used to build Sparse.
+.
+.TP
.B \-gcc-base-dir \fIdir\fR
Look for compiler-provided system headers in \fIdir\fR/include/ and \fIdir\fR/include-fixed/.
.
diff --git a/symbol.c b/symbol.c
index 334f9df2..90149e5a 100644
--- a/symbol.c
+++ b/symbol.c
@@ -534,9 +534,7 @@ const char* get_type_name(enum type type)
[SYM_STRUCT] = "struct",
[SYM_UNION] = "union",
[SYM_ENUM] = "enum",
- [SYM_TYPEDEF] = "typedef",
[SYM_TYPEOF] = "typeof",
- [SYM_MEMBER] = "member",
[SYM_BITFIELD] = "bitfield",
[SYM_LABEL] = "label",
[SYM_RESTRICT] = "restrict",
@@ -745,7 +743,7 @@ static const struct ctype_declare {
} ctype_declaration[] = {
{ &bool_ctype, SYM_BASETYPE, MOD_UNSIGNED, &bits_in_bool, &max_int_alignment, &int_type },
{ &void_ctype, SYM_BASETYPE, 0, NULL, NULL, NULL },
- { &type_ctype, SYM_BASETYPE, MOD_TYPE, NULL, NULL, NULL },
+ { &type_ctype, SYM_BASETYPE, 0, NULL, NULL, NULL },
{ &incomplete_ctype,SYM_BASETYPE, 0, NULL, NULL, NULL },
{ &bad_ctype, SYM_BASETYPE, 0, NULL, NULL, NULL },
diff --git a/symbol.h b/symbol.h
index ac43b314..4e7e437b 100644
--- a/symbol.h
+++ b/symbol.h
@@ -64,9 +64,7 @@ enum type {
SYM_STRUCT,
SYM_UNION,
SYM_ENUM,
- SYM_TYPEDEF,
SYM_TYPEOF,
- SYM_MEMBER,
SYM_BITFIELD,
SYM_LABEL,
SYM_RESTRICT,
@@ -80,7 +78,7 @@ enum keyword {
KW_MODIFIER = 1 << 1,
KW_QUALIFIER = 1 << 2,
KW_ATTRIBUTE = 1 << 3,
- KW_STATEMENT = 1 << 4,
+ // KW UNUSED = 1 << 4,
KW_ASM = 1 << 5,
KW_MODE = 1 << 6,
KW_SHORT = 1 << 7,
@@ -224,7 +222,7 @@ struct symbol {
#define MOD_UNSIGNED 0x00004000
#define MOD_EXPLICITLY_SIGNED 0x00008000
-#define MOD_TYPE 0x00010000
+ // MOD UNUSED 0x00010000
#define MOD_USERTYPE 0x00020000
#define MOD_CHAR 0x00040000
#define MOD_SHORT 0x00080000
@@ -375,7 +373,7 @@ static inline int is_signed_type(struct symbol *sym)
static inline int is_type_type(struct symbol *type)
{
- return (type->ctype.modifiers & MOD_TYPE) != 0;
+ return type == &type_ctype;
}
static inline int is_ptr_type(struct symbol *type)
diff --git a/target.c b/target.c
index c2ab5549..90097818 100644
--- a/target.c
+++ b/target.c
@@ -58,6 +58,27 @@ int enum_alignment = 4;
void init_target(void)
{
switch (arch_mach) {
+ case MACH_I386:
+ case MACH_MIPS32:
+ case MACH_PPC32:
+ case MACH_RISCV32:
+ case MACH_SPARC32:
+ case MACH_S390:
+ if (arch_m64 == ARCH_LP64)
+ arch_mach++;
+ break;
+ case MACH_X86_64:
+ case MACH_MIPS64:
+ case MACH_PPC64:
+ case MACH_RISCV64:
+ case MACH_SPARC64:
+ case MACH_S390X:
+ if (arch_m64 == ARCH_LP32)
+ arch_mach--;
+ break;
+ }
+
+ switch (arch_mach) {
case MACH_X86_64:
if (arch_m64 == ARCH_LP64)
break;
@@ -97,6 +118,7 @@ void init_target(void)
switch (arch_mach) {
case MACH_ARM:
case MACH_MIPS32:
+ case MACH_S390:
case MACH_S390X:
case MACH_SPARC32:
bits_in_longdouble = 64;
diff --git a/validation/arch/arm.c b/validation/arch/arm.c
new file mode 100644
index 00000000..4eb804de
--- /dev/null
+++ b/validation/arch/arm.c
@@ -0,0 +1,27 @@
+__arm__
+__aarch64__
+__i386__
+__x86_64__
+__LP64__
+__BYTE_ORDER__
+__SIZEOF_INT__
+__SIZEOF_LONG__
+__SIZE_TYPE__
+
+/*
+ * check-name: arch/arm
+ * check-command: sparse --arch=arm -E $file
+ *
+ * check-output-start
+
+1
+__aarch64__
+__i386__
+__x86_64__
+__LP64__
+1234
+4
+4
+unsigned int
+ * check-output-end
+ */
diff --git a/validation/arch/arm64.c b/validation/arch/arm64.c
new file mode 100644
index 00000000..12f839cc
--- /dev/null
+++ b/validation/arch/arm64.c
@@ -0,0 +1,23 @@
+__aarch64__
+__x86_64__
+__LP64__
+__BYTE_ORDER__
+__SIZEOF_INT__
+__SIZEOF_LONG__
+__SIZE_TYPE__
+
+/*
+ * check-name: arch/arm64
+ * check-command: sparse --arch=arm64 -E $file
+ *
+ * check-output-start
+
+1
+__x86_64__
+1
+1234
+4
+8
+unsigned long
+ * check-output-end
+ */
diff --git a/validation/arch/mips32.c b/validation/arch/mips32.c
new file mode 100644
index 00000000..339218b6
--- /dev/null
+++ b/validation/arch/mips32.c
@@ -0,0 +1,29 @@
+__mips__
+__mips
+__mips64__
+__i386__
+__x86_64__
+__LP64__
+__BYTE_ORDER__
+__SIZEOF_INT__
+__SIZEOF_LONG__
+__SIZE_TYPE__
+
+/*
+ * check-name: arch/mips32
+ * check-command: sparse --arch=mips32 -E $file
+ *
+ * check-output-start
+
+1
+32
+__mips64__
+__i386__
+__x86_64__
+__LP64__
+4321
+4
+4
+unsigned int
+ * check-output-end
+ */
diff --git a/validation/arch/riscv64.c b/validation/arch/riscv64.c
new file mode 100644
index 00000000..9da7a7de
--- /dev/null
+++ b/validation/arch/riscv64.c
@@ -0,0 +1,27 @@
+__riscv
+__riscv_xlen
+__i386__
+__x86_64__
+__LP64__
+__BYTE_ORDER__
+__SIZEOF_INT__
+__SIZEOF_LONG__
+__SIZE_TYPE__
+
+/*
+ * check-name: arch/riscv64
+ * check-command: sparse --arch=riscv64 -E $file
+ *
+ * check-output-start
+
+1
+64
+__i386__
+__x86_64__
+1
+1234
+4
+8
+unsigned long
+ * check-output-end
+ */