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

--- Comment #9 from Alexander Grund <alexander.gr...@tu-dresden.de> ---
> Note that when the union type is visible in the access path then GCC allows 
> punning without further restrictions. Thus the accesses as written above are 
> OK.

Now I have to ask again for clarification because this seemingly contradicts
your previous statement. So let me try to state the previous question again:

Given a pointer `slot_type* slot` (where slot_type is the union as defined
before) is it legal to access `slot->value.first`, `slot->mutable_value.first`,
`slot->key` interchangeably?

In all 3 accesses the union is visible in the access path (if I understood that
correctly) so the type punning should be ok, shouldn't it?

> the circumstances have been so there's incentive to do an invalid 
> transform... 

So is this indeed a GCC bug which may be fixed or gone latent?

Otherwise, maybe the construction is the problem? What Abseil basically does is
allocating a (suitably aligned) buffer of chars and in-place constructing those
slot_type unions/pairs there as needed (i.e. similar to std::vector)
After abstractions what basically happens is:

// alloc buffer done, then:
slot_type* slot_buffer = reinterpret_cast<slot_type*>(buffer);

// on emplace:
size_t x = ...;
slot_type* slot = slot_buffer + x;
new(slot) slot_type;
new(&slot->mutable_value) pair<const K, V>(k, v);
slot_type* slot2 = slot_buffer + x; // same as before, actually done through
the iterator
idx_vec[i] = slot2->value.second;


My suspicion is, that GCC loads the value of slot2 before constructing the
object, at least sometimes. Printing the values in the vector often shows a run
of zeroes before some other (potentially correct) values. I'd guess the correct
values happen, when no insertion took place, i.e. the construction was done
already in a prior loop iteration.

Reply via email to