[llvm-bugs] [Bug 47673] New: GNU extension alignof(expression) incorrectly returns preferred alignment

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Sep 28 16:09:18 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=47673

            Bug ID: 47673
           Summary: GNU extension alignof(expression) incorrectly returns
                    preferred alignment
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C
          Assignee: unassignedclangbugs at nondot.org
          Reporter: jyknight at google.com
                CC: blitzrakete at gmail.com, dgregor at apple.com,
                    efriedma at quicinc.com, erik.pilkington at gmail.com,
                    llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk

After adjusting for explicit alignment attributes on a decl, alignof(name)
falls back to the _preferred_ alignment of the decl's type. This is broken if
the decl isn't actually allocated at preferred alignment. 

An object will be aligned to the preferred alignment when creating complete
objects on the stack or as a global. But, Decls aren't always referring to a
newly-created complete object, and in some cases, like function parameters, the
alignment can be ABI-mandated to be less than the preferred alignment.

To solve this, we could try to be "smart" and return the preferred alignment
when we know this to be correct. But, I think it's probably better to simply
make alignof(expr) be equivalent to alignof(decltype(var)) adjusted by the
explicit alignment attributes on the decl.

Some examples of the problems:

clang -fsyntax-only -target powerpc-aix -xc++ - <<EOF
struct A { double x; };
static_assert(alignof(A) == 4, ""); // ABI alignment
static_assert(__alignof__(A) == 8, ""); // Preferred alignment

void f(A* a) {static_assert(alignof(*a) == 4, ""); } // correct
void f(A& a) {static_assert(alignof(a) == 8, ""); } // incorrect
void f(int x, A a) { static_assert(alignof(a) == 8, ""); } // incorrect
A f() {
    A a{1};
    static_assert(alignof(a) == 8, ""); // incorrect
    return a;
}
EOF

Some of the problems cannot happen anywhere except AIX, because that's the only
target where aggregates have ABI alignment != preferred alignment. But
elsewhere, references are still an issue:

clang -fsyntax-only -target i386-linux-gnu -xc++ - <<EOF
static_assert(alignof(double) == 4, ""); // ABI alignment
static_assert(__alignof__(double) == 8, ""); // Preferred alignment
void f(double* a) {static_assert(alignof(*a) == 4, ""); } // correct
void f(double& a) {static_assert(alignof(a) == 8, ""); } // incorrect
EOF


FWIW, it looks like GCC has a bug in alignof(expr) as well -- it seems to
always return the preferred alignment, no matter what.

gcc -o /dev/null -c -m32 -xc++ - <<EOF
static_assert(alignof(double) == 4, ""); // ABI alignment
static_assert(__alignof__(double) == 8, ""); // Preferred alignment
void f(double* a) {static_assert(alignof(*a) == 8, ""); } // incorrect
void f(double& a) {static_assert(alignof(a) == 8, ""); } // incorrect
EOF

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200928/787dd358/attachment-0001.html>


More information about the llvm-bugs mailing list