This is an archive of the discontinued LLVM Phabricator instance.

[AST] Add msvc-specific C++11 attributes
AbandonedPublic

Authored by RIscRIpt on Sep 14 2022, 5:23 AM.

Details

Summary
  • 'msvc::no_tls_guard', first appeared in MSVC toolchain 14.25.28610
  • 'msvc::known_semantics', first appeared in MSVC toolchain 14.27.29110
  • 'msvc::noop_dtor', first appeared in MSVC toolchain 14.28.29333
  • 'msvc::constexpr', first appeared in MSVC toolchain 14.33.31629

Closes #57696

Diff Detail

Event Timeline

RIscRIpt created this revision.Sep 14 2022, 5:23 AM
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: jdoerfert. · View Herald Transcript
RIscRIpt requested review of this revision.Sep 14 2022, 5:23 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 14 2022, 5:23 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Thank you for the patch! I'm wondering what the goal is for these changes. We don't typically add attributes to Clang that don't have any effect unless there's a very compelling reason to do so. Are you intending to add semantics for these attributes in follow-up patches?

RIscRIpt added a comment.EditedSep 15 2022, 1:51 PM

I'm wondering what the goal is for these changes. ... Are you intending to add semantics for these attributes in follow-up patches?

To be honest, I wasn't planning to do any of follow-up patches. I made a patch for internal usage at my job, and decided to submit it upstream.
The main reason I (we) need this patch is that we need to be able to parse MSVC-specific code (in the current case - detect constexpr functions). Since Visual Studio 17.3 (MSVC 14.33.31629), Microsoft's STL library added [[msvc::constexpr]] attribute, which is not documented yet, but makes a function to act like a constexpr function: see this godbolt sample (i.e. forbids non-constexpr statements inside).

To make the patch complete, I decided to browse previous Microsoft's STL versions and see which vendor specific (msvc::) attributes they added previously; in this patch I added all attributes I was able to find.

We don't typically add attributes to Clang that don't have any effect unless there's a very compelling reason to do so.

Theoretically, I could re-submit (or adjust this) patch, which would add support for [[msvc::constexpr]] attribute with semantic meaning of constexpr for functions (for code parsed with -fms-extensions flag). Regarding other attributes - unfortunately they are either poorly documented, or not documented at all, so I can drop commits for these attributes.

*Edit:* Please, let me know how we can proceed - either I abandon the patch; or add support only for [[msvc::constexpr]], or any other way of proceeding further?

aaron.ballman added a subscriber: erichkeane.

I'm wondering what the goal is for these changes. ... Are you intending to add semantics for these attributes in follow-up patches?

To be honest, I wasn't planning to do any of follow-up patches. I made a patch for internal usage at my job, and decided to submit it upstream.
The main reason I (we) need this patch is that we need to be able to parse MSVC-specific code (in the current case - detect constexpr functions). Since Visual Studio 17.3 (MSVC 14.33.31629), Microsoft's STL library added [[msvc::constexpr]] attribute, which is not documented yet, but makes a function to act like a constexpr function: see this godbolt sample (i.e. forbids non-constexpr statements inside).

To make the patch complete, I decided to browse previous Microsoft's STL versions and see which vendor specific (msvc::) attributes they added previously; in this patch I added all attributes I was able to find.

We don't typically add attributes to Clang that don't have any effect unless there's a very compelling reason to do so.

Theoretically, I could re-submit (or adjust this) patch, which would add support for [[msvc::constexpr]] attribute with semantic meaning of constexpr for functions (for code parsed with -fms-extensions flag). Regarding other attributes - unfortunately they are either poorly documented, or not documented at all, so I can drop commits for these attributes.

*Edit:* Please, let me know how we can proceed - either I abandon the patch; or add support only for [[msvc::constexpr]], or any other way of proceeding further?

Thanks for the information! Roping in @erichkeane as attribute code owner to make sure he's on board with the idea, but my suggestion is to only support [[msvc::constexpr]] with the semantic meaning of constexpr. It's a good question as to whether we want to support that only when passing -fms-extensions or not (it seems like a generally useful attribute); we don't do the same for GNU attributes, but maybe we don't want to follow that pattern? This will be the first attribute we add with the msvc vendor namespace.

If you find there's a good reason to upstream the other ones, we can certainly consider it. FWIW, one Microsoft-specific attribute I know people have been asking about is [[msvc::no_unique_address]]. See https://github.com/llvm/llvm-project/issues/49358 for more details. Not suggesting you're on the hook for that or anything, just pointing it out in case you wanted to work on that one at some point.

I'm wondering what the goal is for these changes. ... Are you intending to add semantics for these attributes in follow-up patches?

To be honest, I wasn't planning to do any of follow-up patches. I made a patch for internal usage at my job, and decided to submit it upstream.
The main reason I (we) need this patch is that we need to be able to parse MSVC-specific code (in the current case - detect constexpr functions). Since Visual Studio 17.3 (MSVC 14.33.31629), Microsoft's STL library added [[msvc::constexpr]] attribute, which is not documented yet, but makes a function to act like a constexpr function: see this godbolt sample (i.e. forbids non-constexpr statements inside).

To make the patch complete, I decided to browse previous Microsoft's STL versions and see which vendor specific (msvc::) attributes they added previously; in this patch I added all attributes I was able to find.

We don't typically add attributes to Clang that don't have any effect unless there's a very compelling reason to do so.

Theoretically, I could re-submit (or adjust this) patch, which would add support for [[msvc::constexpr]] attribute with semantic meaning of constexpr for functions (for code parsed with -fms-extensions flag). Regarding other attributes - unfortunately they are either poorly documented, or not documented at all, so I can drop commits for these attributes.

*Edit:* Please, let me know how we can proceed - either I abandon the patch; or add support only for [[msvc::constexpr]], or any other way of proceeding further?

Thanks for the information! Roping in @erichkeane as attribute code owner to make sure he's on board with the idea, but my suggestion is to only support [[msvc::constexpr]] with the semantic meaning of constexpr. It's a good question as to whether we want to support that only when passing -fms-extensions or not (it seems like a generally useful attribute); we don't do the same for GNU attributes, but maybe we don't want to follow that pattern? This will be the first attribute we add with the msvc vendor namespace.

If you find there's a good reason to upstream the other ones, we can certainly consider it. FWIW, one Microsoft-specific attribute I know people have been asking about is [[msvc::no_unique_address]]. See https://github.com/llvm/llvm-project/issues/49358 for more details. Not suggesting you're on the hook for that or anything, just pointing it out in case you wanted to work on that one at some point.

I agree with Aaron here, there isn't much value in the "do nothing" attributes, I believe the 'unknown attribute' warning for them is superior to an ignored attribute.

A functional msvc::constexpr would be acceptable, however, I'm having a difficult time figuring out the purpose of it, it seems like it is just a 'constepr keyword' replacement?

clang/lib/Sema/SemaStmtAttr.cpp
296

Typically we try to do the ::Create function that is generated for attributes, rather than placement new. I realize we are consistently inconsistent...

but my suggestion is to only support [[msvc::constexpr]] with the semantic meaning of constexpr

Sounds good to me.

It's a good question as to whether we want to support that only when passing -fms-extensions or not (it seems like a generally useful attribute); we don't do the same for GNU attributes, but maybe we don't want to follow that pattern? This will be the first attribute we add with the msvc vendor namespace.

IMO, this attribute is a clearly Microsoft's extension, thus it should be available only when -fms-extensions are enabled.

If you find there's a good reason to upstream the other ones, we can certainly consider it.

I don't see any good reason for other attributes to be added.

FWIW, one Microsoft-specific attribute I know people have been asking about is [[msvc::no_unique_address]]

Thanks for letting me know.

The current patch is my first attempt to contribute to LLVM; I am afraid it would take me some effort to implement semantics of [[msvc::no_unique_address]], so I'd like to focus only on [[msvc::constexpr]] in current patch.

A functional msvc::constexpr would be acceptable, however, I'm having a difficult time figuring out the purpose of it, it seems like it is just a 'constexpr keyword' replacement?

I don't know how it works internally, but judging by its behavior - yes it's a constexpr replacement with some extended functionality (my guess is that they wanted to do some constexpr magic, and staying compatible with the standard at the same time), and there's a few information available online:

Merged an MSVC-specific attribute, allowing the compiler to improve its handling of constexpr dynamic allocation and constexpr unique_ptr. [1]

// Determine if we should use [[msvc::constexpr]] to allow for "extended constexpr" in Visual C++. [2]

Browsing MSVC 14.33.31629 include headers I can see that this attribute is mostly used in operator new functions: either as a decorator of the function or the return statement.

I guess the best way to make this attribute compatible with MSVC would be ask someone at Microsoft, but I'm not sure who to reach out.

Meanwhile I'll adjust current patch to focus only [[msvc::constexpr]] attribute.

I believe the 'unknown attribute' warning for them is superior to an ignored attribute.

By the way, I'd like to take opportunity and ask what do you think of adding clang-specific compiler flag, which would add all unknown attributes to the AST in a string form (e.g. [[attr1]] -> AST::UnknownAttr{"attr1"}? Would you be interested in such patch?

[1] https://github.com/microsoft/STL/wiki/Changelog

[2] 14.33.31629\include\vcruntime.h

FWIW, one Microsoft-specific attribute I know people have been asking about is [[msvc::no_unique_address]]

Thanks for letting me know.

The current patch is my first attempt to contribute to LLVM; I am afraid it would take me some effort to implement semantics of [[msvc::no_unique_address]], so I'd like to focus only on [[msvc::constexpr]] in current patch.

No worries, thanks for at least thinking about it!

A functional msvc::constexpr would be acceptable, however, I'm having a difficult time figuring out the purpose of it, it seems like it is just a 'constexpr keyword' replacement?

It's a conforming extension in older language modes like C++98, where we couldn't steal the constexpr keyword because it's not reserved, which is one benefit to it. Does MSVC support this as far back as C++98?

I believe the 'unknown attribute' warning for them is superior to an ignored attribute.

By the way, I'd like to take opportunity and ask what do you think of adding clang-specific compiler flag, which would add all unknown attributes to the AST in a string form (e.g. [[attr1]] -> AST::UnknownAttr{"attr1"}? Would you be interested in such patch?

We would be, but it's tricky. The idea we've had in mind for a while is to add an UnknownAttr type which wraps information the parser was able to scrape together. Things like the vendor namespace and attribute name are quite easy to keep around and would be a good initial offering. However, attribute arguments are going to be more difficult to handle because they can be arbitrary token soup rather than code which forms a valid AST node. e.g., [[foo("oh no!")]] isn't bad but [[foo(we don't even know what this is)]] and we can't even necessarily save off tokens for it because it could contain punctuation which isn't a valid token by itself, like ' without a terminating single quote). So the initial offering could save the source range of the parens for the arguments (this way you can at least get back to the text in the source code if you need to), but I don't know that we have a good idea how to handle exposing the argument information.

I am afraid it would take me some effort to implement semantics of [[msvc::no_unique_address]], so I'd like to focus only on [[msvc::constexpr]] in current patch.

Just for context, [[msvc::no_unique_address]] is 100% like the standardized [[no_unique_address]], but MSFT was... exceedingly cautious... about introducing this, as - even for an explicitly opt-in new feature - someone might have compiled code containing [[no_unique_address]] at a time when it was a no-op in their compiler (as an unknown attribute), and changing the semantics after the fact would have violated their very strict compatibility guarantees.

I assume the reasoning behind [[msvc::constexpr]] to be along the same lines.

It's a conforming extension in older language modes like C++98, where we couldn't steal the constexpr keyword because it's not reserved, which is one benefit to it. Does MSVC support this as far back as C++98?

Tbh, I cannot understand your question in relation to your statement, and where did you get that statement from 🙂

Does MSVC support this as far back as C++98?

I don't know. AFAIK - no.

@h-vetinari thanks for your input.

I'll try to update this patch as per our discussion:

  1. [[msvc::constexpr]] handle like constexpr for functions with -fms-extensions (according to MSVC error message: C7687: [[msvc::constexpr]] may only be applied to statements and functions); I won't implement semantic meaning for statements, as I am now aware of it and there's no constexpr effect on statements.
  2. Possibly take a look at [[msvc::no_unique_address]]

It's a conforming extension in older language modes like C++98, where we couldn't steal the constexpr keyword because it's not reserved, which is one benefit to it. Does MSVC support this as far back as C++98?

Tbh, I cannot understand your question in relation to your statement, and where did you get that statement from 🙂

Ah, I forgot that MSVC's /std: flag only goes as far back as C++14. I was wondering two things: 1) does MSVC support [[]] attributes in C++ modes earlier than C++11 (moot, there is no C++ earlier than 14 for MSVC) and 2) does MSVC support [[msvc::constexpr]] in C++ modes earlier than C++11 (also moot). If the answer to both of those questions was "yes", then I'd understand why this attribute exists (it would be a conforming extension in those language modes, where they could not expose constexpr as a keyword). Now I'm wondering why the attribute exists at all. If it's functionally equivalent to constexpr as a keyword, what are the use cases for the attribute?

Now I'm wondering why the attribute exists at all. If it's functionally equivalent to constexpr as a keyword, what are the use cases for the attribute?

I'm guessing something to do with ABI-compatibility with artefacts produced by their older compilers (though I have no idea what scenario they have come up with that would break). It's also for a very recent version (17.3, the last non-preview release as of writing), and I cannot find documentation for it.

Though while searching for it, I stumbled over https://reviews.llvm.org/D110485, which relates to [[no_unique_address]] & how it's incompatible to use it for clang on windows if MSVC doesn't.

I am new to arc, I tried arc diff --edit --verbatim as it's said in the docs, but it still created a new revision: https://reviews.llvm.org/D134458

clang/lib/Sema/SemaStmtAttr.cpp
296

I could address this, but could you please provide an example? Because all handle functions in this file use placement new.

RIscRIpt abandoned this revision.EditedSep 22 2022, 1:07 PM

Now I'm wondering why the attribute exists at all. If it's functionally equivalent to constexpr as a keyword, what are the use cases for the attribute?

It appears that [[msvc::constexpr]] does not make a function constexpr, but if [[msvc::constexpr]] is used in a function definition and in a call to that function, then the annotated function call can be evaluated during constant evaluation: https://godbolt.org/z/3MPTsz6Yn

Apparently this is used to implement constexpr std::construct_at, which needs to call placement operator new, but the latter is not constexpr.