================ @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify %s +// expected-no-diagnostics + +[[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: Add support for [[msvc::constexpr]] constructor ---------------- RIscRIpt wrote:
Note: this is a long-term TODO, which is quite difficult to implement with reasonably small changes. Please let me know, how you typically deal with such cases. --- Redacted comment from https://reviews.llvm.org/D134475#4288759: Regarding on absolute matching MSVC implementation, I am not sure we will be able to achieve it with reasonable changes. I am skeptical, because I discovered the following test case: (which you see in the code). It's a valid code for MSVC; nothing special https://godbolt.org/z/znnaonEhM However supporting this code seems to be difficult in Clang: `S2` fails checks of "literal type" in this callstack: 1. [clang::CXXRecordDecl::isLiteral](https://github.com/llvm/llvm-project/blob/d27897ade53ab6f983e442f24880260eed26238a/clang/include/clang/AST/DeclCXX.h#L1425-L1451) 2. [clang::Type::isLiteralType](https://github.com/llvm/llvm-project/blob/d27897ade53ab6f983e442f24880260eed26238a/clang/lib/AST/Type.cpp#L2795) 3. [CheckLiteralType](https://github.com/llvm/llvm-project/blob/d27897ade53ab6f983e442f24880260eed26238a/clang/lib/AST/ExprConstant.cpp#L2392-L2397) We have information about `CanEvalMSConstexpr` only in `CheckLiteralType`. So, currently, I don't see how we can reasonably check whether `S2` is a valid literal type in context of `[[msvc::constexpr]]`. Two obvious ugly solutions are: 1. Copy all checks from `clang::CXXRecordDecl::isLiteral` to `CheckLiteralType` - two places shall be maintained. 2. Propagate `CanEvalMSConstexpr` down to `clang::CXXRecordDecl::isLiteral`. We could add bool args for both `clang::CXXRecordDecl::isLiteral` and `clang::Type::isLiteralType`. But I don't think it's reasonable for supporting rare vendor-specific attribute. Or is it? I'll try to dive into this problem again, when I start addressing another round of review comments. https://github.com/llvm/llvm-project/pull/71300 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits