Bug 451082 - [C++11] Add support for 'alignof' and 'alignas'
Summary: [C++11] Add support for 'alignof' and 'alignas'
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-parser (show other bugs)
Version: Next   Edit
Hardware: All All
: P3 normal with 4 votes (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 395568
  Show dependency tree
 
Reported: 2014-11-12 03:01 EST by Nathan Ridge CLA
Modified: 2020-09-04 15:20 EDT (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Ridge CLA 2014-11-12 03:01:41 EST
Specified in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf.

Note that for alignof, we appear to support the GCC extension '__alignof', but not the C++11 'alignof'.
Comment 1 Sergey Prigogin CLA 2015-01-21 17:35:58 EST
Commit http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=2c9a404d44e449b558f0e5a87e925c6e1cd080c0 added support for 'alignof'.
Comment 2 CDT Genie CLA 2015-01-22 01:00:05 EST
*** cdt git genie on behalf of Sergey Prigogin ***

    Bug 451082 - Added support for 'alignof'

[*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=2c9a404d44e449b558f0e5a87e925c6e1cd080c0
Comment 3 CDT Genie CLA 2015-01-22 01:00:07 EST
*** cdt git genie on behalf of Sergey Prigogin ***

    Bug 451082 - Added support for 'alignof'

[*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=0cdcaa2a492f315c42a9f2ad656d6dc98e185211
Comment 4 Marc Khouzam CLA 2015-01-22 12:14:52 EST
Does this deserver a note in the N&N?
https://wiki.eclipse.org/CDT/User/NewIn86
Comment 5 Sergey Prigogin CLA 2015-01-22 12:53:56 EST
(In reply to Marc Khouzam from comment #4)
> Does this deserver a note in the N&N?

I don't think so.
Comment 6 Eclipse Genie CLA 2015-03-03 03:50:39 EST
New Gerrit change created: https://git.eclipse.org/r/43060
Comment 7 Nathan Ridge CLA 2015-03-03 03:56:10 EST
The patch in comment 6 adds keyword syntax-coloring for 'alignof' and 'alignas'. (The keywords were added to the lexer in the patch in comment 1, but to get syntax-colored they had to be added to KeywordsSets as well.)

The remaining work in this bug is:

  - Parser support for 'alignas'.

  - Semantics support for 'alignas'. I believe this will involve
    storing an optional evaluation for the requested alignment of
    a variable in the index, instantiating it as necessary, and
    evaluating it during an alignment calculation.
Comment 9 Nathan Ridge CLA 2015-03-06 03:27:27 EST
To make matters more fun, C11 also has this functionality, but there it's spelt _Alignof and _Alignas.
Comment 10 Eclipse Genie CLA 2015-03-14 02:31:24 EDT
New Gerrit change created: https://git.eclipse.org/r/43846
Comment 11 Eclipse Genie CLA 2015-03-14 02:31:29 EDT
New Gerrit change created: https://git.eclipse.org/r/43847
Comment 12 Nathan Ridge CLA 2015-03-14 02:35:05 EDT
The patch in comment 10 adds lexer support for '_Alignas' and '_Alignof' to C. (It also removes support for the C++ form, 'alignof', in C, which appears to have been added by mistake.)

The patch in comment 11 adds parser support for alignment specifiers ('alignas' in C++ and '_Alignas' in C). I shared as much of the implementation between C and C++ as I could. I had to introduce a new type of ambiguous node to represent the ambiguity between a type-id and an expression inside an alignment specifier.

Semantics support remains to be implemented.
Comment 15 Nathan Ridge CLA 2015-03-15 23:02:27 EDT
(In reply to Nathan Ridge from comment #12)
> Semantics support remains to be implemented.

I have no immediate plans to work on semantics support. (From an IDE's perspective, the use case is fairly narrow: it only affects the compile-time evaluation of expressions that use 'alignof', and inside the 'alignof' reference a variable or type that has (or has a field that has) an alignment-specifier.)

If someone else would like to work on the semantics support, please feel free (and I'm happy to provide guidance if desired).
Comment 16 Marc Khouzam CLA 2015-06-24 13:07:35 EDT
(In reply to Nathan Ridge from comment #12)
> The patch in comment 10 adds lexer support for '_Alignas' and '_Alignof' to
> C. (It also removes support for the C++ form, 'alignof', in C, which appears
> to have been added by mistake.)
> 
> The patch in comment 11 adds parser support for alignment specifiers
> ('alignas' in C++ and '_Alignas' in C). I shared as much of the
> implementation between C and C++ as I could. I had to introduce a new type
> of ambiguous node to represent the ambiguity between a type-id and an
> expression inside an alignment specifier.

Do these deserve an N&N entry?
https://wiki.eclipse.org/CDT/User/NewIn87
Comment 17 Nathan Ridge CLA 2015-06-24 13:34:52 EDT
(In reply to Marc Khouzam from comment #16)
> Do these deserve an N&N entry?
> https://wiki.eclipse.org/CDT/User/NewIn87

I think so; I added one. Thanks for pointing it out.
Comment 18 Danilo Margarido CLA 2015-10-20 12:50:35 EDT
Support is still incomplete.
Filed bug #475739 with what's missing.
Comment 19 Danilo Margarido CLA 2016-10-06 12:01:31 EDT
We can mark this bug as resolved already.
Comment 20 Nathan Ridge CLA 2016-10-06 16:49:29 EDT
As mentioned in comment 12, semantics support for 'alignas' remains to be implemented.

Here's a piece of example code that demonstrates this:

  struct alignas(8) S {
      int x;
  };

  template <int> struct A {};

  template <> struct A<8> {
      void foo();
  };

  int main() {
      A<alignof(S)>().foo();
  }

CDT marks the call to foo() as an error, because it thinks alignof(S) is 4, because we're not propagating the alignas(8) into alignof calculations.
Comment 21 Atif CLA 2017-04-07 05:37:52 EDT
Syntax error with Struct Declarations
------------------------------------

in Mars 4.5.2 with CDT 8.8.1 

the following statement does not show syntax error 

int alignas(8) x;  

however following struct declaration shows syntax error
but of course compiles perfectly with gcc and clang

// every object of type sse_t will be aligned to 16-byte boundary
struct alignas(16) sse_t
{
  float sse_data[4];
};
Comment 22 Danilo Margarido CLA 2017-04-07 11:21:56 EDT
Atif, you should upgrade to eclipse oxygen and COST 9.3.
Comment 23 Danilo Margarido CLA 2017-04-07 11:23:18 EDT
*CDT 9.3, dang it autocorrect.
Comment 24 Nathan Ridge CLA 2017-04-07 22:48:02 EDT
(In reply to Atif from comment #21)
> however following struct declaration shows syntax error
> but of course compiles perfectly with gcc and clang
> 
> // every object of type sse_t will be aligned to 16-byte boundary
> struct alignas(16) sse_t
> {
>   float sse_data[4];
> };

As Danilo has pointed out, this works with the latest version. It was fixed for CDT >= 9.0 in bug 475739.
Comment 25 Atif CLA 2017-04-10 05:57:29 EDT
Danilo  and Nathan, I just downloaded Oxygen M6 CDT package and yes it does work and all syntax errors have disappeared.
Thanks for pointing it out.

BR
Atif
Comment 26 Nathan Ridge CLA 2017-11-13 14:54:07 EST
I discovered today that you're allowed put a pack expansion inside an alignas():

template <typename... T>
struct S {
  alignas(T...) int x;  // fine
};
S<long double, unsigned long> s;  // also instantiates fine

but, interestingly, not an explicit comma-separated list of types:

struct S {
  alignas(long double, unsigned long) int x;  // doesn't parse
};

We parse the pack expansion form fine, but it will mean extra work when implementing semantics support for it.
Comment 27 Danilo Margarido CLA 2017-11-14 06:36:19 EST
(In reply to Nathan Ridge from comment #26)
> I discovered today that you're allowed put a pack expansion inside an
> alignas():

It has been that way since C++11 [1].
The second form isn't allowed because it's not what pack expansion translates into.
`alignas(T...)` is basically `alignas(T0) alignas(T1) alignas(T2) ... alignas(Tn)`.

[1] http://en.cppreference.com/w/cpp/language/alignas
Comment 28 Nathan Ridge CLA 2017-11-14 12:47:15 EST
(In reply to Danilo Margarido from comment #27)
> (In reply to Nathan Ridge from comment #26)
> > I discovered today that you're allowed put a pack expansion inside an
> > alignas():
> 
> It has been that way since C++11 [1].

Yeah. I just realized it yesterday :)

> The second form isn't allowed because it's not what pack expansion
> translates into.
> `alignas(T...)` is basically `alignas(T0) alignas(T1) alignas(T2) ...
> alignas(Tn)`.

Thanks, that makes a bit more sense. It also makes it a bit easier to model, since instead of allowing multiple types in a single alignment-specifier, we just need to support multiple alignment specifiers in a decl-specifier-seq (which we in fact already do).

I still think `alignas(T)...` would have been a more natural syntax given that expansion, but this is not the place to debate C++ language design :)
Comment 29 Norbert Lange CLA 2019-11-05 05:50:38 EST
Seems like its still not supporting all usecases.
This will yield an syntax error (while being valid C++):

static alignas(16) char s_SendBuffer[32];
Comment 30 Nathan Ridge CLA 2019-11-05 18:06:01 EST
(In reply to Norbert Lange from comment #29)
> (while being valid C++):

Nope. Clang rejects this:

$ clang++ -c test.cpp
test.cpp:1:8: error: an attribute list cannot appear here
static alignas(16) char s_SendBuffer[32];
       ^~~~~~~~~~~
1 error generated.

Grammatically, an attribute-specifier-seq ("alignas(16)") can appear before or after the decl-specifier-seq ("static char"), but not in the middle.
Comment 31 Nathan Ridge CLA 2019-11-05 18:27:31 EST
(In reply to Nathan Ridge from comment #30)
> Grammatically, an attribute-specifier-seq ("alignas(16)") can appear before
> or after the decl-specifier-seq ("static char"), but not in the middle.

For completeness, I should mention that, while putting the "alignas(16)" after the "static char" is grammatically valid, it's still semantically ill-formed (although CDT does not diagnose this):

$ clang++ -c test.cpp
test.cpp:1:13: error: 'alignas' attribute cannot be applied to types
static char alignas(16) s_SendBuffer[32];
            ^
1 error generated.

The only correct way to write this declaration in C++ is with the alignas(16) at the beginning:

alignas(16) static char s_SendBuffer[32];