<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - GNU extension alignof(expression) incorrectly returns preferred alignment"
href="https://bugs.llvm.org/show_bug.cgi?id=47673">47673</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>GNU extension alignof(expression) incorrectly returns preferred alignment
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>C
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>jyknight@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>blitzrakete@gmail.com, dgregor@apple.com, efriedma@quicinc.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>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</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>