Bug 69502 - attribute aligned reduces alignment contrary to documentation
Summary: attribute aligned reduces alignment contrary to documentation
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: documentation
Depends on:
Blocks:
 
Reported: 2016-01-26 21:42 UTC by Martin Sebor
Modified: 2024-04-15 05:35 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-06-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2016-01-26 21:42:05 UTC
The GCC manual says that:

"The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well. See below."

However, GCC accepts the attribute in typedef definitions that decrease the alignment of the defined type.  The program below fails with all versions of GCC I've tried, all the way back to 4.5.

Either the documentation should be adjusted to reflect this feature or the implementation should be changed to reject (or ignore with a warning) definitions of types that would reduce a type's alignment requirement.

As a data point, the current versions of C and C++ disallow alignment specification on typedefs.  As another data point, of the three GCC-compatible compilers I tested, Sun cc successfully compiles the code below (with warnings), while Clang and Intel CC fail in the same assertions as GCC.

$ cat u.c && /home/msebor/build/gcc-trunk-git/gcc/xgcc -B/home/msebor/build/gcc-trunk-git/gcc -S -Wall -Wextra -Wpedantic -o/dev/null -std=c11 u.c

#define Align(N)    __attribute__ ((aligned (N)))
#define Assert(e)   typedef int A [1 - 2 * !(e)]

void f (void)
{
  typedef int I32 Align (32);
  Assert (__alignof__ (I32) == 32);

  typedef I32 Align (1) I1;
  Assert (__alignof__ (I1) == __alignof__ (I32));

  typedef int Align (2) I2;
  Assert (__alignof__ (I2) == __alignof__ (int));
}
u.c: In function ‘f’:
u.c:2:33: error: size of array ‘A’ is negative
 #define Assert(e)   typedef int A [1 - 2 * !(e)]
                                 ^

u.c:10:3: note: in expansion of macro ‘Assert’
   Assert (__alignof__ (I1) == __alignof__ (I32));
   ^~~~~~

u.c:2:33: error: size of array ‘A’ is negative
 #define Assert(e)   typedef int A [1 - 2 * !(e)]
                                 ^

u.c:13:3: note: in expansion of macro ‘Assert’
   Assert (__alignof__ (I2) == __alignof__ (int));
   ^~~~~~
Comment 1 Martin Sebor 2017-06-01 19:23:14 UTC
The Common Variable Attributes section of the manual mentions the following:

When used as part of a typedef, the aligned attribute can both increase and decrease alignment, and specifying the packed attribute generates a warning.

There is at least one test in the GCC test suite that exercises the ability to decrease the alignment of a typedef (gcc/testsuite/gcc.dg/misaligned-expand-2.c  added in r185336) so this is a documentation bug for not documenting the feature in the right section of the manual (Common Type Attributes).

Confirming based bug 51628, comment #24.
Comment 2 Martin Sebor 2017-06-06 16:52:14 UTC
*** Bug 65672 has been marked as a duplicate of this bug. ***
Comment 3 sandra 2018-11-12 06:23:49 UTC
Author: sandra
Date: Mon Nov 12 06:23:16 2018
New Revision: 266025

URL: https://gcc.gnu.org/viewcvs?rev=266025&root=gcc&view=rev
Log:
2018-11-11  Sandra Loosemore  <sandra@codesourcery.com>

	PR c/69502

	gcc/
	* doc/extend.texi (Common Type Attributes): For the align type
	attribute, copy language about decreasing alignment from the
	corresponding variable attribute.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/doc/extend.texi
Comment 4 sandra 2018-11-12 06:30:51 UTC
Fixed on trunk.
Comment 5 Sven 2018-11-12 14:28:03 UTC
(In reply to sandra from comment #4)
> Fixed on trunk.

It's good thing that the documentation reflects the behavior of gcc. 

But on the other hand, having the align attribute work in both directions is a bad idea, IMHO.

Using an attribute to specify an alignment guarantee (setting a lower bound on the actual alignment) is a benign thing.

However, forcing lowering the alignment guarantee usually indicates some sort of "trickery" that may force the compiler to circumvent certain limitations of the underlying platform.

These two concepts (increasing alignment, lowering alignment) should be kept strictly separate.