[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[creduce-bugs] clang-delta segfault in creduce-2.1.0-135-gd74eff6
Hi,
while running creduce from github using clang 3.4.2 I encountered a
segfault with clang-delta using the attached source file.
HTH Janne
#include <stdint.h>
#include <string.h>
#define av_always_inline __attribute__((always_inline)) inline
#define av_noinline __attribute__((noinline))
#define av_const __attribute__((const))
#define av_unused __attribute__((unused))
#define FFMIN(a,b) a > b ? b : a
static av_always_inline av_const uint8_t av_clip_uint8(int a) {
if (a&~0xFF) return -a>>31;
else return a;
}
# define AV_RB32(x) \
((x)[0] << 24 | \
(x)[1] << 16 | \
(x)[2] << 8 | \
(x)[3])
#ifndef NEG_USR32
# define NEG_USR32(a,s) a>>32-s
#endif
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits_plus8;
}
GetBitContext;
#define OPEN_READER(name, gb) \
unsigned int name ## _index = gb->index; \
unsigned int av_unused name ## _cache = 0; \
unsigned int av_unused name ## _size_plus8 = gb->size_in_bits_plus8
#define CLOSE_READER(name, gb) gb->index = name ## _index
# define UPDATE_CACHE(name, gb) name ## _cache = \
AV_RB32(gb->buffer + (name ## _index >> 3)) << (name ## _index & 7)
# define SKIP_COUNTER(name, gb, num) \
name ## _index = FFMIN(name ## _size_plus8, name ## _index + num)
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
#define SHOW_UBITS(name, gb, num) NEG_USR32(name ## _cache, num)
#define GET_CACHE(name, gb) name ## _cache
int get_bits_tmp;
static inline unsigned int get_bits(GetBitContext *s, int n) {
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
get_bits_tmp = SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return get_bits_tmp;
}
static inline unsigned int get_bits1(GetBitContext *s) {
unsigned int index = s->index;
uint8_t result = s->buffer[index >> 3];
if (s->index < s->size_in_bits_plus8) index++;
s->index = index;
return result;
}
int init_get_bits_ret = 0;
static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size) {
s->buffer = buffer;
s->size_in_bits_plus8 = bit_size + 8;
return init_get_bits_ret;
}
const uint8_t ff_zigzag_direct[64] = {
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 };
static int av_log2(unsigned v) {
return 31 - __builtin_clz(v|1);
}
static const uint8_t ff_golomb_vlc_len[512]={
19,17,15,15,13,13,13,13,11,11,11,11,11,11,11,11,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
static const int8_t ff_se_golomb_vlc_code[512]={
17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15, 4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
static inline int get_se_golomb(GetBitContext *gb) {
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf >= 1 << 27) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_se_golomb_vlc_code[buf];
}
else {
int log = 2 * av_log2(buf) - 31;
buf >>= log;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
if (buf & 1) buf = -(buf >> 1);
else buf = buf >> 1;
return buf;
}
}
typedef struct Frame {
uint8_t *data[3];
int linesize[3];
}
Frame;
typedef struct FICThreadContext {
int16_t __attribute__ ((aligned )) block[64];
uint8_t *src;
int slice_h;
int src_size;
int y_off;
}
FICThreadContext;
typedef struct FICContext {
int key_frame;
Frame *frame;
const uint8_t *qmat;
int aligned_width, aligned_height;
int num_slices, slice_h;
}
FICContext;
static const uint8_t fic_qmat_hq[64] = {
1, 2, 2, 2, 3, 3, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 3, 3, 3, 4, 4, 5, 2, 3, 3, 3, 4, 4, 5, 6, 3, 3, 3, 4, 4, 5, 6, 7, 3, 3, 3, 4, 4, 5, 7, 7, 3, 3, 4, 4, 5, 7, 7, 7, };
static av_always_inline void fic_idct(int16_t *blk, int step, int shift) {
const int t0 = 27246 * blk[3 * step] + 18405 * blk[5 * step];
const int t1 = 27246 * blk[5 * step] - 18405 * blk[3 * step];
const int t2 = 6393 * blk[7 * step] + 32139 * blk[1 * step];
const int t3 = 6393 * blk[1 * step] - 32139 * blk[7 * step];
const int t4 = 5793 * (t2 + t0 + 0x800 >> 12);
const int t5 = 5793 * (t3 + t1 + 0x800 >> 12);
const int t6 = t2 - t0;
const int t7 = t3 - t1;
const int t8 = 17734 * blk[2 * step] - 42813 * blk[6 * step];
const int t9 = 17734 * blk[6 * step] + 42814 * blk[2 * step];
const int tA = (blk[0 * step] - blk[4 * step] << 15) + (1 << shift - 1);
const int tB = (blk[0 * step] + blk[4 * step] << 15) + (1 << shift - 1);
blk[0 * step] = t4 + t9 + tB >> shift;
blk[1 * step] = t6 + t7 + t8 + tA >> shift;
blk[2 * step] = t6 - t7 - t8 + tA >> shift;
blk[3 * step] = t5 - t9 + tB >> shift;
blk[4 * step] = -t5 - t9 + tB >> shift;
blk[5 * step] = -(t6 - t7) - t8 + tA >> shift;
blk[6 * step] = -(t6 + t7) + t8 + tA >> shift;
blk[7 * step] = -t4 + t9 + tB >> shift;
}
int fic_idct_put_j;
static void fic_idct_put(uint8_t *dst, int stride, int16_t *block) {
int i;
int16_t *ptr;
ptr = block;
for (i = 0;
i < 8;
i++) {
fic_idct(ptr, 8, 13);
ptr++;
}
ptr = block;
for (i = 0;
i < 8;
i++) {
fic_idct(ptr, 1, 20);
ptr += 8;
}
ptr = block;
for (fic_idct_put_j = 0;
fic_idct_put_j < 8;
fic_idct_put_j++) {
for (i = 0;
i < 8;
i++) dst[i] = av_clip_uint8(ptr[i]);
dst += stride;
ptr += 8;
}
}
static int fic_decode_block(FICContext *ctx, GetBitContext *gb, uint8_t *dst, int stride, int16_t *block) {
int i, num_coeff;
/* Is it a skip block? */ if (get_bits1(gb)) ;
memset(block, 0, sizeof*block * 64);
num_coeff = get_bits(gb, 7);
for (i = 0;
i < num_coeff;
i++) block[ff_zigzag_direct[i]] = get_se_golomb(gb) * ctx->qmat[ff_zigzag_direct[i]];
fic_idct_put(dst, stride, block);
return 0;
}
int fic_decode_slice_y;
static av_noinline int fic_decode_slice(FICContext *ctx, void *tdata) {
FICThreadContext *tctx = tdata;
GetBitContext gb;
uint8_t *src = tctx->src;
int slice_h = tctx->slice_h;
int src_size = tctx->src_size;
int y_off = tctx->y_off;
int x, p;
init_get_bits(&gb, src, src_size * 8);
for (p = 0;
p < 3;
p++) {
int stride = ctx->frame->linesize[p];
uint8_t* dst = ctx->frame->data[p] + (y_off >> !!p) * stride;
for (fic_decode_slice_y = 0;
fic_decode_slice_y < slice_h >> !!p;
fic_decode_slice_y += 8) {
for (x = 0;
x < ctx->aligned_width >> !!p;
x += 8) {
int ret;
if (ret = fic_decode_block(ctx, &gb, dst + x, stride, tctx->block) != 0) return ret;
}
dst += 8 * stride;
}
}
return 0;
}
// this should reproduce the crash:
// /home/janne/.local/libexec/clang_delta --transformation=param-to-local --counter=2 /home/janne/src/aarch64-gcc-4.9-libav-fate-fic-avi-bug/clang_delta_crash_tmp_fileBh6bkm.c