int has more than tree bits, so you must mask the result of a bitwise negation like this:
int flip(int n) {
    // bitwise AND with 0b111 = 7, this will clear all but the last 3 bits
    return ~n & 0b111;
}
The reason you got -6 is because int is typically represented in two's complement, where -6 is all 1-bits but ends with 010. You must remove these leading 1-bits to get the correct result.
Generally, I would recommend not using bitwise operations with signed numbers and instead do the following:
unsigned flip(unsigned n) {
    return ~n & 0b111;
}
// this version works with any number of bits, not just 3
unsigned flip(unsigned n, unsigned bits) {
    unsigned mask = (1 << bits) - 1;
    return ~n & mask;
}
If you don't know how many bits your number has, you must first find the most significant bit. In the most naive way, it can be done like this:
unsigned log2(unsigned val)
{
    unsigned result = 0;
    while (val >>= 1) {
        ++result;
    }
    return result;
}
unsigned variable_flip(unsigned n) {
    return flip(n, log2(n));
}
You can find more efficient solutions here.
For example:
unsigned log2_debruijn(uint32_t val) {
    static const unsigned MultiplyDeBruijnBitPosition[32] = {0, 9,  1,  10, 13, 21, 2,  29, 11, 14, 16, 18, 22, 25, 3, 30,
                                                          8, 12, 20, 28, 15, 17, 24, 7,  19, 27, 23, 6,  26, 5,  4, 31};
    // first round down to one less than a power of 2
    // this step is not necessary if val is a power of 2
    val |= val >> 1;
    val |= val >> 2;
    val |= val >> 4;
    val |= val >> 8;
    val |= val >> 16;
    return MultiplyDeBruijnBitPosition[(val * uint32_t{0x07C4ACDD}) >> 27];
}