[llvm-dev] [cfe-dev] RFC: Enforcing pointer type alignment in Clang

James Y Knight via llvm-dev llvm-dev at lists.llvm.org
Thu Jan 14 22:28:20 PST 2016


(Sorry for the duplicate mail, Richard, I accidentally sent a copy only to
you before.)

On Thu, Jan 14, 2016 at 10:26 PM, Richard Smith via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

>  [1]: That's not completely true, as it's possible to create an object
> that is underaligned for its type:
>
> struct __attribute__((packed)) A {
>   char k;
>   struct B { int n; } b;
> } a;
> A::B *p = &a.b; // Misaligned pointer, now guaranteed OK
> int main() {
>   int *q = &p->n; // UB? UBSan diagnoses this member access
>   return *q; // Obviously UB
> }
>
> It seems that we do need to have some syntactic rules for how far the
> known alignment propagates to handle this case; your proposed rules don't
> do the right thing here.
>
>
I don't think any new rules are really needed here.

With your example, I expect even doing "int x = a.b.n;" to be okay. The
value "a.b" is actually (effectively) typed "struct A::B
__attribute__((aligned(1))) *", and thus fine to access a sub-object of, as
the pointer is NOT misaligned for its type! And similarly, the type of
&a.b.n is "int __attribute__((aligned(1))) *", and also thus not misaligned.

While casting the result of "&a.b" to "A::B *" in the expression "A::B *p =
&a.b" is fine (well, becomes more _explicitly_ fine with your suggested
modification to the standard text), once you've done that, the new type
_does_ require an alignment of alignof(int), and thus, the value of "p" is
misaligned for its type. And so, you can no longer dereference it nor
access members. That seems all fine and sensible to me.

If you need to give a name "p" to the value, you can still do like this:
  typedef struct A::B __attribute__((aligned(1))) misaligned_A_B;
  misaligned_A_B *p = &a.b;
  int x = p->n;

AFAICT, this all works today, as well.

Now, of course, the "aligned" attribute being able to reduce the alignment
of a type -- but only when used in a typedef (!!!) -- is a non-standard GCC
extension which is not even properly documented anywhere. And it fails to
work in some places, like trying to use it as a template parameter (GCC
actually diagnoses that as not working; clang silently ignores it).

So, I'm not saying everything is completely hunky-dory here. But I do think
it's essentially a workable and sane model.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160115/11cb3580/attachment.html>


More information about the llvm-dev mailing list