Skip to content
  • Neil Roberts's avatar
    Don't deref the sample pointer in the wl_container_of macro · a18e3441
    Neil Roberts authored
    The previous implementation of the wl_container_of macro was
    dereferencing the sample pointer in order to get an address of the
    member to calculate the offset. Ideally this shouldn't cause any
    problems because the dereference doesn't actually cause the address to
    be read from so it shouldn't matter if the pointer is uninitialised.
    However this is probably technically invalid and could cause undefined
    behavior. Clang appears to take advantage of this undefined behavior
    and doesn't bother doing the subtraction. It also gives a warning when
    it does this.
    
    The documentation for wl_container_of implies that it should only be
    given an initialised pointer and if that is done then there is no
    problem with clang. However this is quite easy to forget and doesn't
    cause any problems or warnings with gcc so it's quite easy to
    accidentally break clang.
    
    To fix the problem this changes the macro to use pointer -
    offsetof(__typeof__(sample), member) so that it doesn't need to deref
    the sample pointer. This does however require that the __typeof__
    operator is supported by the compiler. In practice we probably only
    care about gcc and clang and both of these happily support the
    operator.
    
    The previous implementation was also using __typeof__ but it had a
    fallback path avoiding it when the operator isn't available. The
    fallback effectively has undefined behaviour and it is targetting
    unknown compilers so it is probably not a good idea to leave it in.
    Instead, this patch just removes it. If someone finds a compiler that
    doesn't have __typeof__ but does work with the old implementation then
    maybe they could add it back in as a special case.
    
    This patch removes the initialisation anywhere where the sample
    pointer was being unitialised before using wl_container_of. The
    documentation for the macro has also been updated to specify that this
    is OK.
    a18e3441