Diagnostic for under-aligned pointers

Hi,

Does it make sense to emit a diagnostic when we implicitly cast a pointer to
another pointer type with a higher required alignment?

Here's an example where this might be useful. The pointer "uiptr" is at least
1-byte aligned, but it's implicitly cast to "int *" (and treated as at least
8-byte aligned):

    extern int printf(const char *S, ...);
    
    int load_aligned(int *ptr) {
      printf("Alignment of ptr: %lu\n", __alignof__(ptr));
      return *ptr;
    }
    
    typedef int unaligned_int __attribute__((aligned(1)));
    
    int main() {
      unaligned_int ui = 0;
      unaligned_int *__attribute__((aligned(1))) uiptr = &ui;
      printf("Alignment of uiptr: %lu\n", __alignof__(uiptr));
      return load_aligned(uiptr);
    }

When compiled with ToT clang, this program prints out:

    Alignment of uiptr: 1
    Alignment of ptr: 8

IIUC, users should only see the warning if they opt into lowering the alignment
of a pointer. I wouldn't expect this to be too noisy, but I don't have any data
on this.

It's true that we can catch this issue with ubsan, but only when the value of
"uiptr" is actually not 8-byte aligned. Besides, it might be helpful to have a
compile-time check for this (e.g in situations where it's tricky to deploy the
sanitizer runtime).

best,
vedant

I was just reading about -Wcast-align the other day, isn’t this what it does? Or does it only trigger for explicit casts?

  • Kim

Thanks for the pointer!

I tried out my example with -Wcast-align -Weverything but couldn't trigger a
diagnostic. Based on test/Sema/warn-cast-align.c, it seems like this produces
exactly the kind of diagnostic I'd like. Maybe it's only tested for explicit
casts to avoid false positives?

vedant

IIUC, this kind of warning can hint at subtle bug in the code.
If so, it seems valuable to me!

Hi,

Does it make sense to emit a diagnostic when we implicitly cast a pointer to
another pointer type with a higher required alignment?

Here's an example where this might be useful. The pointer "uiptr" is at least
1-byte aligned, but it's implicitly cast to "int *" (and treated as at least
8-byte aligned):

   extern int printf(const char *S, ...);

   int load_aligned(int *ptr) {
     printf("Alignment of ptr: %lu\n", __alignof__(ptr));
     return *ptr;
   }

Are we talking about the alignment of the pointer variable or the alignment of the data ptr points to? If it’s the latter, I’ve seen requests from people who wanted clang to issue a warning when compiling the following code, so perhaps it is something we should look into.

typedef uint64_t unaligned_u64 __attribute__((aligned(1)));
unaligned_u64 a;
uint64_t *b = &a; /* should warn with -Wcast-align? */

Hi,

Does it make sense to emit a diagnostic when we implicitly cast a pointer to
another pointer type with a higher required alignment?

Here's an example where this might be useful. The pointer "uiptr" is at least
1-byte aligned, but it's implicitly cast to "int *" (and treated as at least
8-byte aligned):

  extern int printf(const char *S, ...);

  int load_aligned(int *ptr) {
    printf("Alignment of ptr: %lu\n", __alignof__(ptr));
    return *ptr;
  }

Are we talking about the alignment of the pointer variable or the alignment of the data ptr points to? If it’s the latter, I’ve seen requests from people who wanted clang to issue a warning when compiling the following code, so perhaps it is something we should look into.

typedef uint64_t unaligned_u64 __attribute__((aligned(1)));
unaligned_u64 a;
uint64_t *b = &a; /* should warn with -Wcast-align? */

I was just asking about the first situation (where the pointer to the data
itself is under-aligned). But, I've also seen a request for a diagnostic when
the pointed-to data is under-aligned.

vedant