-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[clang-cl] Add support for [[msvc::constexpr]] C++11 attribute #71300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
3be36c6
[clang-cl] Add support for [[msvc::constexpr]] C++11 attribute
RIscRIpt 8d62660
[clang-cl] Bump default -fms-compatibility-version to 19.33
RIscRIpt fda6092
fixup! [clang-cl] Bump default -fms-compatibility-version to 19.33
RIscRIpt 616895e
fixup! [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute
RIscRIpt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -ast-dump -verify %s | FileCheck %s | ||
// expected-no-diagnostics | ||
|
||
// CHECK: used f1 'bool ()' | ||
// CHECK: MSConstexprAttr 0x{{[0-9a-f]+}} <col:3, col:9> | ||
[[msvc::constexpr]] bool f1() { return true; } | ||
|
||
// CHECK: used constexpr f2 'bool ()' | ||
// CHECK-NEXT: CompoundStmt 0x{{[0-9a-f]+}} <col:21, col:56> | ||
// CHECK-NEXT: AttributedStmt 0x{{[0-9a-f]+}} <col:23, col:53> | ||
// CHECK-NEXT: MSConstexprAttr 0x{{[0-9a-f]+}} <col:25, col:31> | ||
// CHECK-NEXT: ReturnStmt 0x{{[0-9a-f]+}} <col:43, col:53> | ||
constexpr bool f2() { [[msvc::constexpr]] return f1(); } | ||
static_assert(f2()); | ||
|
||
struct S1 { | ||
// CHECK: used vm 'bool ()' virtual | ||
// CHECK: MSConstexprAttr 0x{{[0-9a-f]+}} <col:7, col:13> | ||
[[msvc::constexpr]] virtual bool vm() { return true; } | ||
|
||
// CHECK: used constexpr cm 'bool ()' | ||
// CHECK-NEXT: CompoundStmt 0x{{[0-9a-f]+}} <col:25, col:60> | ||
// CHECK-NEXT: AttributedStmt 0x{{[0-9a-f]+}} <col:27, col:57> | ||
// CHECK-NEXT: MSConstexprAttr 0x{{[0-9a-f]+}} <col:29, col:35> | ||
// CHECK-NEXT: ReturnStmt 0x{{[0-9a-f]+}} <col:47, col:57> | ||
constexpr bool cm() { [[msvc::constexpr]] return vm(); } | ||
}; | ||
static_assert(S1{}.cm()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify %s | ||
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++17 -verify %s | ||
|
||
// Check explicitly invalid code | ||
|
||
void runtime() {} // expected-note {{declared here}} | ||
|
||
[[msvc::constexpr]] void f0() { runtime(); } // expected-error {{constexpr function never produces a constant expression}} \ | ||
// expected-note {{non-constexpr function 'runtime' cannot be used in a constant expression}} | ||
[[msvc::constexpr]] constexpr void f1() {} // expected-error {{attribute 'msvc::constexpr' cannot be applied to the constexpr function 'f1'}} | ||
#if __cplusplus >= 202202L | ||
[[msvc::constexpr]] consteval void f2() {} // expected-error {{attribute 'msvc::constexpr' cannot be applied to the consteval function 'f1'}} | ||
#endif | ||
|
||
struct B1 {}; | ||
struct D1 : virtual B1 { // expected-note {{virtual base class declared here}} | ||
[[msvc::constexpr]] D1() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} | ||
}; | ||
|
||
struct [[msvc::constexpr]] S2{}; // expected-error {{'constexpr' attribute only applies to functions and return statements}} | ||
|
||
// Check invalid code mixed with valid code | ||
|
||
[[msvc::constexpr]] int f4(int x) { return x > 1 ? 1 + f4(x / 2) : 0; } // expected-note {{non-constexpr function 'f4' cannot be used in a constant expression}} \ | ||
// expected-note {{declared here}} \ | ||
// expected-note {{declared here}} \ | ||
// expected-note {{declared here}} | ||
constexpr bool f5() { [[msvc::constexpr]] return f4(32) == 5; } // expected-note {{in call to 'f4(32)'}} | ||
static_assert(f5()); // expected-error {{static assertion expression is not an integral constant expression}} \ | ||
// expected-note {{in call to 'f5()'}} | ||
|
||
int f6(int x) { [[msvc::constexpr]] return x > 1 ? 1 + f6(x / 2) : 0; } // expected-note {{declared here}} \ | ||
// expected-note {{declared here}} | ||
constexpr bool f7() { [[msvc::constexpr]] return f6(32) == 5; } // expected-error {{constexpr function never produces a constant expression}} \ | ||
// expected-note {{non-constexpr function 'f6' cannot be used in a constant expression}} \ | ||
// expected-note {{non-constexpr function 'f6' cannot be used in a constant expression}} | ||
static_assert(f7()); // expected-error {{static assertion expression is not an integral constant expression}} \ | ||
// expected-note {{in call to 'f7()'}} | ||
|
||
constexpr bool f8() { // expected-error {{constexpr function never produces a constant expression}} | ||
[[msvc::constexpr]] f4(32); // expected-error {{'constexpr' attribute only applies to functions and return statements}} \ | ||
// expected-note {{non-constexpr function 'f4' cannot be used in a constant expression}} \ | ||
// expected-note {{non-constexpr function 'f4' cannot be used in a constant expression}} | ||
[[msvc::constexpr]] int i5 = f4(32); // expected-error {{'constexpr' attribute only applies to functions and return statements}} | ||
return i5 == 5; | ||
} | ||
static_assert(f8()); // expected-error {{static assertion expression is not an integral constant expression}} \ | ||
// expected-note {{in call to 'f8()'}} | ||
|
||
#if __cplusplus == 201702L | ||
struct S1 { [[msvc::constexpr]] virtual bool vm() const { return true; } }; // expected-error {{attribute 'msvc::constexpr' ignored, it only applies to function definitions and return statements}} | ||
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify=supported %s | ||
RIscRIpt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.32 -std=c++20 -verify=unsupported %s | ||
// supported-no-diagnostics | ||
|
||
[[nodiscard]] | ||
[[msvc::constexpr]] // unsupported-warning {{unknown attribute 'constexpr' ignored}} | ||
inline void* __cdecl operator new(decltype(sizeof(void*)), void* p) noexcept { return p; } | ||
|
||
namespace std { | ||
constexpr int* construct_at(int* p, int v) { | ||
[[msvc::constexpr]] return ::new (p) int(v); // unsupported-warning {{unknown attribute 'constexpr' ignored}} | ||
} | ||
} | ||
|
||
constexpr bool check_construct_at() { int x; return *std::construct_at(&x, 42) == 42; } | ||
static_assert(check_construct_at()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify %s | ||
|
||
[[msvc::constexpr]] int log2(int x) { [[msvc::constexpr]] return x > 1 ? 1 + log2(x / 2) : 0; } | ||
constexpr bool test_log2() { [[msvc::constexpr]] return log2(32) == 5; } | ||
static_assert(test_log2()); | ||
|
||
[[msvc::constexpr]] int get_value(int x) | ||
{ | ||
switch (x) | ||
{ | ||
case 42: return 1337; | ||
default: | ||
if (x < 0) [[msvc::constexpr]] return log2(-x); | ||
else return x; | ||
} | ||
} | ||
|
||
constexpr bool test_complex_expr() { | ||
[[msvc::constexpr]] return get_value(get_value(42) - 1337 + get_value(-32) - 5 + (get_value(1) ? get_value(0) : get_value(2))) == get_value(0); | ||
} | ||
static_assert(test_complex_expr()); | ||
|
||
constexpr bool get_constexpr_true() { return true; } | ||
[[msvc::constexpr]] bool get_msconstexpr_true() { return get_constexpr_true(); } | ||
constexpr bool test_get_msconstexpr_true() { [[msvc::constexpr]] return get_msconstexpr_true(); } | ||
static_assert(test_get_msconstexpr_true()); | ||
|
||
// TODO (#72149): Add support for [[msvc::constexpr]] constructor; this code is valid for MSVC. | ||
struct S2 { | ||
[[msvc::constexpr]] S2() {} | ||
[[msvc::constexpr]] bool value() { return true; } | ||
static constexpr bool check() { [[msvc::constexpr]] return S2{}.value(); } // expected-error {{constexpr function never produces a constant expression}} \ | ||
// expected-note {{non-literal type 'S2' cannot be used in a constant expression}} \ | ||
// expected-note {{non-literal type 'S2' cannot be used in a constant expression}} | ||
}; | ||
static_assert(S2::check()); // expected-error {{static assertion expression is not an integral constant expression}} \ | ||
// expected-note {{in call to 'check()'}} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.