diff options
| -rw-r--r-- | Documentation/IR.rst | 3 | ||||
| -rw-r--r-- | cse.c | 2 | ||||
| -rw-r--r-- | example.c | 2 | ||||
| -rw-r--r-- | lib.c | 2 | ||||
| -rw-r--r-- | lib.h | 1 | ||||
| -rw-r--r-- | linearize.c | 22 | ||||
| -rw-r--r-- | linearize.h | 1 | ||||
| -rw-r--r-- | simplify.c | 1 | ||||
| -rw-r--r-- | sparse-llvm.c | 1 | ||||
| -rw-r--r-- | validation/backend/pointer-sub.c | 2 | ||||
| -rw-r--r-- | validation/cast-kinds-check.c | 2 | ||||
| -rw-r--r-- | validation/cast-weirds.c | 49 | ||||
| -rw-r--r-- | validation/linear/cast-kinds.c | 10 | ||||
| -rw-r--r-- | validation/optim/kill-casts.c | 1 |
14 files changed, 92 insertions, 7 deletions
diff --git a/Documentation/IR.rst b/Documentation/IR.rst index 5b9155f7..56f02318 100644 --- a/Documentation/IR.rst +++ b/Documentation/IR.rst @@ -270,6 +270,9 @@ They all have the following signature: .. op:: OP_SCAST Cast to signed integer. +.. op:: OP_UTPTR + Cast from unsigned integer to pointer type. + .. op:: OP_PTRCAST Cast to pointer. @@ -94,6 +94,7 @@ void cse_collect(struct instruction *insn) case OP_CAST: case OP_SCAST: case OP_PTRCAST: + case OP_UTPTR: /* * This is crap! Many "orig_types" are the * same as far as casts go, we should generate @@ -241,6 +242,7 @@ static int insn_compare(const void *_i1, const void *_i2) case OP_CAST: case OP_SCAST: case OP_PTRCAST: + case OP_UTPTR: /* * This is crap! See the comments on hashing. */ @@ -81,6 +81,7 @@ static const char *opcodes[] = { [OP_UCVTF] = "ucvtf", [OP_SCVTF] = "scvtf", [OP_FCVTF] = "fcvtf", + [OP_UTPTR] = "utptr", [OP_PTRCAST] = "ptrcast", [OP_CALL] = "call", [OP_SLICE] = "slice", @@ -1414,6 +1415,7 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state) break; case OP_CAST: case OP_SCAST: case OP_PTRCAST: + case OP_UTPTR: case OP_FCVTU: case OP_FCVTS: case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: @@ -258,6 +258,7 @@ int Wdefault_bitfield_sign = 0; int Wdesignated_init = 1; int Wdo_while = 0; int Winit_cstring = 0; +int Wint_to_pointer_cast = 1; int Wenum_mismatch = 1; int Wsparse_error = 0; int Wmemcpy_max_count = 1; @@ -687,6 +688,7 @@ static const struct flag warnings[] = { { "do-while", &Wdo_while }, { "enum-mismatch", &Wenum_mismatch }, { "init-cstring", &Winit_cstring }, + { "int-to-pointer-cast", &Wint_to_pointer_cast }, { "memcpy-max-count", &Wmemcpy_max_count }, { "non-pointer-null", &Wnon_pointer_null }, { "old-initializer", &Wold_initializer }, @@ -149,6 +149,7 @@ extern int Wdo_while; extern int Wenum_mismatch; extern int Wsparse_error; extern int Winit_cstring; +extern int Wint_to_pointer_cast; extern int Wmemcpy_max_count; extern int Wnon_pointer_null; extern int Wold_initializer; diff --git a/linearize.c b/linearize.c index a7d2b068..0f40682c 100644 --- a/linearize.c +++ b/linearize.c @@ -268,6 +268,7 @@ static const char *opcodes[] = { [OP_UCVTF] = "ucvtf", [OP_SCVTF] = "scvtf", [OP_FCVTF] = "fcvtf", + [OP_UTPTR] = "utptr", [OP_PTRCAST] = "ptrcast", [OP_INLINED_CALL] = "# call", [OP_CALL] = "call", @@ -452,6 +453,7 @@ const char *show_instruction(struct instruction *insn) case OP_FCVTU: case OP_FCVTS: case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: + case OP_UTPTR: case OP_PTRCAST: buf += sprintf(buf, "%s <- (%d) %s", show_pseudo(insn->target), @@ -1221,7 +1223,17 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src) return OP_BADOP; } case MTYPE_PTR: - return OP_PTRCAST; + switch (stype) { + case MTYPE_UINT: + case MTYPE_SINT: + if (is_ptr_type(src)) // must be a void pointer + return OP_PTRCAST;// FIXME: to be removed? + return OP_UTPTR; + case MTYPE_PTR: + return OP_PTRCAST; + default: + return OP_BADOP; + } case MTYPE_UINT: case MTYPE_SINT: switch (stype) { @@ -1254,6 +1266,14 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol * switch (opcode) { case OP_NOP: return src; + case OP_UTPTR: + if (from->bit_size == to->bit_size) + break; + if (src == value_pseudo(0)) + break; + if (Wint_to_pointer_cast) + warning(to->pos, "non size-preserving integer to pointer cast"); + break; default: break; } diff --git a/linearize.h b/linearize.h index b513d549..c5d98a2d 100644 --- a/linearize.h +++ b/linearize.h @@ -226,6 +226,7 @@ enum opcode { OP_FCVTU, OP_FCVTS, OP_UCVTF, OP_SCVTF, OP_FCVTF, + OP_UTPTR, OP_PTRCAST, OP_UNOP_END = OP_PTRCAST, @@ -1223,6 +1223,7 @@ int simplify_instruction(struct instruction *insn) case OP_FCVTU: case OP_FCVTS: case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: + case OP_UTPTR: case OP_PTRCAST: return simplify_cast(insn); case OP_PHI: diff --git a/sparse-llvm.c b/sparse-llvm.c index 75cac8f9..8732f989 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -1045,6 +1045,7 @@ static void output_insn(struct function *fn, struct instruction *insn) case OP_FCVTF: output_op_fpcast(fn, insn); break; + case OP_UTPTR: case OP_PTRCAST: output_op_ptrcast(fn, insn); break; diff --git a/validation/backend/pointer-sub.c b/validation/backend/pointer-sub.c index 3cb8f5a9..5c99f4fa 100644 --- a/validation/backend/pointer-sub.c +++ b/validation/backend/pointer-sub.c @@ -13,5 +13,5 @@ long subvx3(void *p, int a) { return (p - ((void*)0)) ^ 3; } /* * check-name: pointer-sub - * check-command: sparsec -Wno-decl -c $file -o tmp.o + * check-command: sparsec -Wno-int-to-pointer-cast -Wno-decl -c $file -o tmp.o */ diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c index 1f10e0ec..736ab391 100644 --- a/validation/cast-kinds-check.c +++ b/validation/cast-kinds-check.c @@ -20,5 +20,7 @@ linear/cast-kinds.c:29:51: warning: cast wasn't removed linear/cast-kinds.c:34:52: warning: cast wasn't removed linear/cast-kinds.c:35:54: warning: cast wasn't removed linear/cast-kinds.c:36:52: warning: cast wasn't removed +linear/cast-kinds.c:37:42: warning: non size-preserving integer to pointer cast +linear/cast-kinds.c:38:44: warning: non size-preserving integer to pointer cast * check-error-end */ diff --git a/validation/cast-weirds.c b/validation/cast-weirds.c new file mode 100644 index 00000000..136137b4 --- /dev/null +++ b/validation/cast-weirds.c @@ -0,0 +1,49 @@ +typedef unsigned int uint; +typedef unsigned long ulong; + +static int * int_2_iptr(int a) { return (int *)a; } +static int * uint_2_iptr(uint a) { return (int *)a; } + +static void * int_2_vptr(int a) { return (void *)a; } +static void * uint_2_vptr(uint a) { return (void *)a; } + +/* + * check-name: cast-weirds + * check-command: test-linearize -m64 $file + * + * check-error-start +cast-weirds.c:4:42: warning: non size-preserving integer to pointer cast +cast-weirds.c:5:44: warning: non size-preserving integer to pointer cast + * check-error-end + * + * check-output-start +int_2_iptr: +.L0: + <entry-point> + utptr.64 %r2 <- (32) %arg1 + ret.64 %r2 + + +uint_2_iptr: +.L2: + <entry-point> + utptr.64 %r5 <- (32) %arg1 + ret.64 %r5 + + +int_2_vptr: +.L4: + <entry-point> + scast.64 %r8 <- (32) %arg1 + ret.64 %r8 + + +uint_2_vptr: +.L6: + <entry-point> + cast.64 %r11 <- (32) %arg1 + ret.64 %r11 + + + * check-output-end + */ diff --git a/validation/linear/cast-kinds.c b/validation/linear/cast-kinds.c index d07a9419..4449d0af 100644 --- a/validation/linear/cast-kinds.c +++ b/validation/linear/cast-kinds.c @@ -55,7 +55,7 @@ static double double_2_double(double a) { return a; } /* * check-name: cast-kinds - * check-command: test-linearize -m64 $file + * check-command: test-linearize -Wno-int-to-pointer-cast -m64 $file * * check-output-start uint_2_int: @@ -288,28 +288,28 @@ iptr_2_vptr: int_2_iptr: .L66: <entry-point> - ptrcast.64 %r101 <- (32) %arg1 + utptr.64 %r101 <- (32) %arg1 ret.64 %r101 uint_2_iptr: .L68: <entry-point> - ptrcast.64 %r104 <- (32) %arg1 + utptr.64 %r104 <- (32) %arg1 ret.64 %r104 long_2_iptr: .L70: <entry-point> - ptrcast.64 %r107 <- (64) %arg1 + utptr.64 %r107 <- (64) %arg1 ret.64 %r107 ulong_2_iptr: .L72: <entry-point> - ptrcast.64 %r110 <- (64) %arg1 + utptr.64 %r110 <- (64) %arg1 ret.64 %r110 diff --git a/validation/optim/kill-casts.c b/validation/optim/kill-casts.c index b79335ab..c375f5fb 100644 --- a/validation/optim/kill-casts.c +++ b/validation/optim/kill-casts.c @@ -20,4 +20,5 @@ void foo(struct s *x) * check-output-ignore * check-output-excludes: cast\\. * check-output-excludes: fcvt[us]\\. + * check-output-excludes: utptr\\. */ |
