xref: /llvm-project/clang/test/SemaCXX/ms-constexpr.cpp (revision b3e6ff331925dde24a4707452d657da0fdf7f588)
1*b3e6ff33SRichard Dzenis // RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify %s
2*b3e6ff33SRichard Dzenis 
log2(int x)3*b3e6ff33SRichard Dzenis [[msvc::constexpr]] int log2(int x) { [[msvc::constexpr]] return x > 1 ? 1 + log2(x / 2) : 0; }
test_log2()4*b3e6ff33SRichard Dzenis constexpr bool test_log2() { [[msvc::constexpr]] return log2(32) == 5; }
5*b3e6ff33SRichard Dzenis static_assert(test_log2());
6*b3e6ff33SRichard Dzenis 
get_value(int x)7*b3e6ff33SRichard Dzenis [[msvc::constexpr]] int get_value(int x)
8*b3e6ff33SRichard Dzenis {
9*b3e6ff33SRichard Dzenis   switch (x)
10*b3e6ff33SRichard Dzenis   {
11*b3e6ff33SRichard Dzenis     case 42: return 1337;
12*b3e6ff33SRichard Dzenis     default:
13*b3e6ff33SRichard Dzenis              if (x < 0) [[msvc::constexpr]] return log2(-x);
14*b3e6ff33SRichard Dzenis              else return x;
15*b3e6ff33SRichard Dzenis   }
16*b3e6ff33SRichard Dzenis }
17*b3e6ff33SRichard Dzenis 
test_complex_expr()18*b3e6ff33SRichard Dzenis constexpr bool test_complex_expr() {
19*b3e6ff33SRichard Dzenis   [[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);
20*b3e6ff33SRichard Dzenis }
21*b3e6ff33SRichard Dzenis static_assert(test_complex_expr());
22*b3e6ff33SRichard Dzenis 
get_constexpr_true()23*b3e6ff33SRichard Dzenis constexpr bool get_constexpr_true() { return true; }
get_msconstexpr_true()24*b3e6ff33SRichard Dzenis [[msvc::constexpr]] bool get_msconstexpr_true() { return get_constexpr_true(); }
test_get_msconstexpr_true()25*b3e6ff33SRichard Dzenis constexpr bool test_get_msconstexpr_true() { [[msvc::constexpr]] return get_msconstexpr_true(); }
26*b3e6ff33SRichard Dzenis static_assert(test_get_msconstexpr_true());
27*b3e6ff33SRichard Dzenis 
28*b3e6ff33SRichard Dzenis // TODO (#72149): Add support for [[msvc::constexpr]] constructor; this code is valid for MSVC.
29*b3e6ff33SRichard Dzenis struct S2 {
S2S230*b3e6ff33SRichard Dzenis     [[msvc::constexpr]] S2() {}
valueS231*b3e6ff33SRichard Dzenis     [[msvc::constexpr]] bool value() { return true; }
checkS232*b3e6ff33SRichard Dzenis     static constexpr bool check() { [[msvc::constexpr]] return S2{}.value(); } // expected-error {{constexpr function never produces a constant expression}} \
33*b3e6ff33SRichard Dzenis                                                                                // expected-note {{non-literal type 'S2' cannot be used in a constant expression}} \
34*b3e6ff33SRichard Dzenis                                                                                // expected-note {{non-literal type 'S2' cannot be used in a constant expression}}
35*b3e6ff33SRichard Dzenis };
36*b3e6ff33SRichard Dzenis static_assert(S2::check()); // expected-error {{static assertion expression is not an integral constant expression}} \
37*b3e6ff33SRichard Dzenis                             // expected-note {{in call to 'check()'}}
38