enum variables with defined bit width
The signedness of an enum type according to the C standard is implementation-defined, and thus shouldn't be relied on. However, the code implicitly assumes it's unsigned (a gcc-specific thing?), and uses constructs like this:
```
typedef enum {
ADDR_POLICY_ACCEPT=1,
ADDR_POLICY_REJECT=2,
} addr_policy_action_t;
addr_policy_action_t policy_type:2;
```
What happens to the above case with the MSVC compiler is that it treats the enum type as signed, and writing a '2' makes two's-complement math kick in, so '2' becomes '-2'. One unit test fails because of this, which is how I noticed it. The consequence is that Tor's state can easily destabilize, and impossible execution paths like this could occur:
```
test = 2;
assert( test == 2 ); // triggers
```
There are workarounds, like wrapping the enum in a struct (very ugly), or using an integer type for storage (loss of type info). Ideally stop using bit packing entirely in memory-only structures, and serialize to integer types of exact size when crafting packets (an enum's size is variable in gcc, fixed in msvc).
Here's a list of all offending places for patterns ":N" and ": N", N=1..9:
* circ_id_type_t circ_id_type:2;
* addr_policy_action_t policy_type:2;
* path_state_t path_state : 2;
* addressmap_entry_source_t [3;](3;)
* } state : 3;
* } dir_spool_src : 3;
* saved_location_t saved_location : 3;
**Trac**:
**Username**: ultramage
issue