https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117262

--- Comment #3 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
I see:

(gdb) pt ctor
 <constructor 0x7fffea821390
    type <array_type 0x7fffea7f4930
        type <integer_type 0x7fffea664348 unsigned char sizes-gimplified public
unsigned QI
            size <integer_cst 0x7fffea666048 constant 8>
            unit-size <integer_cst 0x7fffea666060 constant 1>
            align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea664348 precision:8 min <integer_cst 0x7fffea666078 0> max <integer_cst
0x7fffea666018 255>
            pointer_to_this <pointer_type 0x7fffea822540>>
        BLK
        size <integer_cst 0x7fffea7ea2d0 constant 576>
        unit-size <integer_cst 0x7fffea7fff48 constant 72>
        align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea7f4930
        domain <integer_type 0x7fffea7f4888 type <integer_type 0x7fffea664000
sizetype>
            sizes-gimplified DI
            size <integer_cst 0x7fffea644f48 constant 64>
            unit-size <integer_cst 0x7fffea644f60 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea7f4888 precision:64 min <integer_cst 0x7fffea644f78 0> max <integer_cst
0x7fffea7fff30 71>>>
    constant length:1
    idx <integer_cst 0x7fffea644fc0 type <integer_type 0x7fffea6640a8
bitsizetype> constant 0>
    val <raw_data_cst 0x7fffea7f3af0 type <integer_type 0x7fffea664348 unsigned
char>
        constant>>

This mystified me for a while until I saw:

tree.def has:
/* Contents are RAW_DATA_LENGTH and the actual content
   of the raw data, plus RAW_DATA_OWNER for owner of the
   data.  That can be either a STRING_CST, used e.g. when writing
   PCH header, or another RAW_DATA_CST representing data owned by
   libcpp and representing the original range (if possible).
   TREE_TYPE is the type of each of the RAW_DATA_LENGTH elements.  */
DEFTREECODE (RAW_DATA_CST, "raw_data_cst", tcc_constant, 0)

and tree.h has:
#define RAW_DATA_LENGTH(NODE) \
  (RAW_DATA_CST_CHECK (NODE)->raw_data_cst.length)

(gdb) p val->raw_data_cst.str
$11 = 0x7fffea7fa434 "int\nmain ()\n{\n  const unsigned char meow_bytes[] = {\n
   \n  };\n  short m"
(gdb) p val->raw_data_cst.owner
$12 = <string_cst 0x7fffea7fa420>
(gdb) p val->raw_data_cst.length
$13 = 72

It might help if print tree showed the length of a raw_data_cst.

The analyzer doesn't yet know about raw_data_cst and assumes the initializer
has size 1 byte, hence after:

  MEM <unsigned char[72]> [(void *)&meow_bytes] = *.LC0;

the various logic inside binding_map::apply_ctor_pair_to_child_region leads to
get_gassign_result returning:

(gdb) call rhs_sval->dump()
(41): ‘unsigned char[72]’: compound_svalue
╰─ byte 0: ‘unsigned char’ {UNKNOWN(unsigned char)}

i.e. a 72 byte svalue of which only byte 0 has a binding, hence the false
positive.

I'm working on a fix.

Reply via email to