[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -7337,6 +7337,27 @@ static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL)); } +static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!S.getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2022_3)) { +S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) +<< AL << AL.getRange(); +return; + } + auto *FD = cast(D); + if (FD->isConstexprSpecified() || FD->isConsteval()) { +S.Diag(AL.getLoc(), diag::err_ms_constexpr_not_distinct) +<< FD->isConsteval() << FD; +return; + } + if (auto *MD = dyn_cast(FD)) { RIscRIpt wrote: Prior to C++20 `constexpr` functions were not allowed to be `virtual` [cppreference](https://en.cppreference.com/w/cpp/language/constexpr). I know this is an attribute, but this matches MSVC behavior: https://godbolt.org/z/snn6c1EW7 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -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: Created a follow-up #72149. > However, i think we should enable the test, and record the diagnostic to > ensure we show it is invalid for now (along with better showing the TODO). I hope I understood you correctly: I enabled the test, and added `expected-*` comments alongside with `TODO` mentioning 72149. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -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: I thought I could send send all comments at once (like in GitLab or Phabricator), but unfortunately not. I was in process of rebasing and re-running lit tests. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt updated https://github.com/llvm/llvm-project/pull/71300 >From 93be428cb8af34292305741a891ddffe362e9a20 Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Thu, 20 Jul 2023 00:18:50 +0300 Subject: [PATCH 1/2] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute Differential Revision: https://reviews.llvm.org/D134475 --- clang/include/clang/Basic/Attr.td | 8 +++ clang/include/clang/Basic/AttrDocs.td | 16 ++ .../clang/Basic/DiagnosticSemaKinds.td| 10 +++- clang/include/clang/Basic/LangOptions.h | 1 + clang/lib/AST/ExprConstant.cpp| 34 +--- clang/lib/Basic/Targets/OSTargets.cpp | 3 ++ clang/lib/Sema/SemaDecl.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 24 + clang/lib/Sema/SemaDeclCXX.cpp| 5 +- clang/lib/Sema/SemaStmtAttr.cpp | 16 ++ clang/test/AST/ms-constexpr.cpp | 28 ++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaCXX/ms-constexpr-invalid.cpp | 52 +++ clang/test/SemaCXX/ms-constexpr-new.cpp | 16 ++ clang/test/SemaCXX/ms-constexpr.cpp | 37 + 15 files changed, 245 insertions(+), 10 deletions(-) create mode 100644 clang/test/AST/ms-constexpr.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-invalid.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-new.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 31434565becaec6..82395f36c10ec6e 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3614,6 +3614,14 @@ def : MutualExclusions<[Owner, Pointer]>; // Microsoft-related attributes +def MSConstexpr : InheritableAttr { + let LangOpts = [MicrosoftExt]; + let Spellings = [CXX11<"msvc", "constexpr">]; + let Subjects = SubjectList<[Function, Stmt], ErrorDiag, + "functions and statements">; + let Documentation = [MSConstexprDocs]; +} + def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fa6f6acd0c30e88..3f6b64e4cf0c173 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3612,6 +3612,22 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated in the same way as a ``constexpr`` +function if it is evaluated in a constant context of +``[[msvc::constexpr]] return`` statement. +Otherwise, it is treated as a regular function. + +Semantics of this attribute is enabled only under MSVC compatibility +(``-fms-compatibility-version``) 19.33 and later. + }]; +} + def MSNoVTableDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 4614324babb1c91..10b03096a5c9557 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2861,8 +2861,8 @@ def warn_cxx17_compat_constexpr_local_var_no_init : Warning< "is incompatible with C++ standards before C++20">, InGroup, DefaultIgnore; def ext_constexpr_function_never_constant_expr : ExtWarn< - "%select{constexpr|consteval}1 %select{function|constructor}0 never produces a " - "constant expression">, InGroup>, DefaultError; + "%select{constexpr|consteval|[[msvc::constexpr]]}1 %select{function|constructor}0 " + "never produces a constant expression">, InGroup>, DefaultError; def err_attr_cond_never_constant_expr : Error< "%0 attribute expression never produces a constant expression">; def err_diagnose_if_invalid_diagnostic_type : Error< @@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; +def err_ms_constexpr_virtual : Error<"virtual function cannot be [[msvc::constexpr]]">; +def warn_ms_constexpr_no_effect : Warning< + "[[msvc::constexpr]] has effect only on function definitions and return statements">, + InGroup; // C++20 function try blocks in constexpr def ext_constexpr_function_try_block_cxx20 : ExtWarn< diff --git a/clang/include/clang/Basi
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: Oof, sorry, I forgot I should push new changes and rebased changes separately (otherwise "Compare" link does not make sense). If you had checkout `829f8098af96` locally, you can see the diff diff as follows: ``` git range-diff 829f8098af96~2..829f8098af96 7d8b1c0fae42~2..7d8b1c0fae42 ``` 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt updated https://github.com/llvm/llvm-project/pull/71300 >From d2b4e14210d7ac24e4a48407e8dc7dac9d97a549 Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Thu, 20 Jul 2023 00:18:50 +0300 Subject: [PATCH 1/2] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute Differential Revision: https://reviews.llvm.org/D134475 --- clang/include/clang/Basic/Attr.td | 8 +++ clang/include/clang/Basic/AttrDocs.td | 15 ++ .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Basic/LangOptions.h | 1 + clang/lib/AST/ExprConstant.cpp| 34 +--- clang/lib/Basic/Targets/OSTargets.cpp | 3 ++ clang/lib/Sema/SemaDecl.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 25 + clang/lib/Sema/SemaStmtAttr.cpp | 12 + clang/test/AST/ms-constexpr.cpp | 28 ++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaCXX/ms-constexpr-invalid.cpp | 52 +++ clang/test/SemaCXX/ms-constexpr-new.cpp | 16 ++ clang/test/SemaCXX/ms-constexpr.cpp | 37 + 14 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 clang/test/AST/ms-constexpr.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-invalid.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-new.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 03ed6accf700c..21b18c79c93d4 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3638,6 +3638,14 @@ def : MutualExclusions<[Owner, Pointer]>; // Microsoft-related attributes +def MSConstexpr : InheritableAttr { + let LangOpts = [MicrosoftExt]; + let Spellings = [CXX11<"msvc", "constexpr">]; + let Subjects = SubjectList<[Function, ReturnStmt], ErrorDiag, + "functions and return statements">; + let Documentation = [MSConstexprDocs]; +} + def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index be74535e28d8a..c82d920aa9533 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3612,6 +3612,21 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated as if it were a ``constexpr`` function +if it is evaluated in a constant context of ``[[msvc::constexpr]] return`` statement. +Otherwise, it is treated as a regular function. + +Semantics of this attribute is enabled only under MSVC compatibility +(``-fms-compatibility-version``) 19.33 and later. + }]; +} + def MSNoVTableDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6894e22da34e0..629257915d83e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2884,6 +2884,8 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_cannot_be_applied : Error< + "attribute 'msvc::constexpr' cannot be applied to the %select{constexpr|consteval|virtual}0 function %1">; // C++20 function try blocks in constexpr def ext_constexpr_function_try_block_cxx20 : ExtWarn< diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 2d167dd2bdf12..c4979b9a38c0c 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -152,6 +152,7 @@ class LangOptions : public LangOptionsBase { MSVC2019 = 1920, MSVC2019_5 = 1925, MSVC2019_8 = 1928, +MSVC2022_3 = 1933, }; enum SYCLMajorVersion { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 16697e5f076a8..668484c9ed9aa 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -641,6 +641,10 @@ namespace { return false; } +/// Whether we're in a context where [[msvc::constexpr]] evaluation is +/// permitted. See MSConstexprDocs for description of permitted contexts. +bool CanEvalMSConstexpr = false; + private: APValue &createLocal(APValue::LValueBase Base, const void *Key, QualType T, ScopeKind
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt commented: Addressed review comments; updated my tests to use changed diagnostic messages. Next I'll upload my branch rebased onto main. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt edited 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; +def err_ms_constexpr_virtual : Error<"virtual function cannot be [[msvc::constexpr]]">; RIscRIpt wrote: Done. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; RIscRIpt wrote: After the latest changes, this is the only `msvc::constexpr` specific attribute left. What do you think if we use existing diagnostic messages with `constexpr` variant instead of introducing a new diagnostic message? 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; RIscRIpt wrote: You are right, changed. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; +def err_ms_constexpr_virtual : Error<"virtual function cannot be [[msvc::constexpr]]">; +def warn_ms_constexpr_no_effect : Warning< + "[[msvc::constexpr]] has effect only on function definitions and return statements">, RIscRIpt wrote: Tbh, I don't remember my reasoning. I can only say that MSVC at this moment does not emit any warning/error: https://godbolt.org/z/YfMxYPqEx Anyway, I changed subjects Stmt to ReturnStmt. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -217,6 +217,8 @@ C23 Feature Support Non-comprehensive list of changes in this release - +- The default value of `_MSC_VER` was raised from 1920 to 1933. + MSVC 19.33 added undocumented attribute ``[[msvc::constexpr]]``. RIscRIpt wrote: Thanks, applied manually. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -3612,6 +3612,22 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated in the same way as a ``constexpr`` RIscRIpt wrote: Thanks, applied manually. Note, now there are two `if` words nearby. But perhaps it's still better. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -2861,8 +2861,8 @@ def warn_cxx17_compat_constexpr_local_var_no_init : Warning< "is incompatible with C++ standards before C++20">, InGroup, DefaultIgnore; def ext_constexpr_function_never_constant_expr : ExtWarn< - "%select{constexpr|consteval}1 %select{function|constructor}0 never produces a " - "constant expression">, InGroup>, DefaultError; + "%select{constexpr|consteval|[[msvc::constexpr]]}1 %select{function|constructor}0 " RIscRIpt wrote: As you raised concern about `[[` `]]`, and after I saw automatic diagnostic when I changed Subjects to include ReturnStmt, I decided to use `constexpr` variant in my cases. Let me know if we can do better here. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt edited 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt updated https://github.com/llvm/llvm-project/pull/71300 >From 3be36c6100801195f8f1f5167bdaa289bc8cb175 Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Thu, 20 Jul 2023 00:18:50 +0300 Subject: [PATCH 1/2] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute Differential Revision: https://reviews.llvm.org/D134475 --- clang/include/clang/Basic/Attr.td | 8 +++ clang/include/clang/Basic/AttrDocs.td | 15 ++ .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Basic/LangOptions.h | 1 + clang/lib/AST/ExprConstant.cpp| 34 +--- clang/lib/Basic/Targets/OSTargets.cpp | 3 ++ clang/lib/Sema/SemaDecl.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 25 + clang/lib/Sema/SemaStmtAttr.cpp | 12 + clang/test/AST/ms-constexpr.cpp | 28 ++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaCXX/ms-constexpr-invalid.cpp | 52 +++ clang/test/SemaCXX/ms-constexpr-new.cpp | 16 ++ clang/test/SemaCXX/ms-constexpr.cpp | 37 + 14 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 clang/test/AST/ms-constexpr.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-invalid.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-new.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 121ed203829cec..b0a8ef10c500a7 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3646,6 +3646,14 @@ def : MutualExclusions<[Owner, Pointer]>; // Microsoft-related attributes +def MSConstexpr : InheritableAttr { + let LangOpts = [MicrosoftExt]; + let Spellings = [CXX11<"msvc", "constexpr">]; + let Subjects = SubjectList<[Function, ReturnStmt], ErrorDiag, + "functions and return statements">; + let Documentation = [MSConstexprDocs]; +} + def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 88f7c65e6e847b..9dc6a909f07d09 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3657,6 +3657,21 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated as if it were a ``constexpr`` function +if it is evaluated in a constant context of ``[[msvc::constexpr]] return`` statement. +Otherwise, it is treated as a regular function. + +Semantics of this attribute is enabled only under MSVC compatibility +(``-fms-compatibility-version``) 19.33 and later. + }]; +} + def MSNoVTableDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ea08fa84d022cd..28d95ca9b13893 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2884,6 +2884,8 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_cannot_be_applied : Error< + "attribute 'msvc::constexpr' cannot be applied to the %select{constexpr|consteval|virtual}0 function %1">; // C++20 function try blocks in constexpr def ext_constexpr_function_try_block_cxx20 : ExtWarn< diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 2d167dd2bdf128..c4979b9a38c0cf 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -152,6 +152,7 @@ class LangOptions : public LangOptionsBase { MSVC2019 = 1920, MSVC2019_5 = 1925, MSVC2019_8 = 1928, +MSVC2022_3 = 1933, }; enum SYCLMajorVersion { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 986302e1fd225f..90cc0b84f0439c 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -641,6 +641,10 @@ namespace { return false; } +/// Whether we're in a context where [[msvc::constexpr]] evaluation is +/// permitted. See MSConstexprDocs for description of permitted contexts. +bool CanEvalMSConstexpr = false; + private: APValue &createLocal(APValue::LValueBase Base, const void *Key, QualType T,
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt updated https://github.com/llvm/llvm-project/pull/71300 >From 3be36c6100801195f8f1f5167bdaa289bc8cb175 Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Thu, 20 Jul 2023 00:18:50 +0300 Subject: [PATCH 1/4] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute Differential Revision: https://reviews.llvm.org/D134475 --- clang/include/clang/Basic/Attr.td | 8 +++ clang/include/clang/Basic/AttrDocs.td | 15 ++ .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Basic/LangOptions.h | 1 + clang/lib/AST/ExprConstant.cpp| 34 +--- clang/lib/Basic/Targets/OSTargets.cpp | 3 ++ clang/lib/Sema/SemaDecl.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 25 + clang/lib/Sema/SemaStmtAttr.cpp | 12 + clang/test/AST/ms-constexpr.cpp | 28 ++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaCXX/ms-constexpr-invalid.cpp | 52 +++ clang/test/SemaCXX/ms-constexpr-new.cpp | 16 ++ clang/test/SemaCXX/ms-constexpr.cpp | 37 + 14 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 clang/test/AST/ms-constexpr.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-invalid.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-new.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 121ed203829cec..b0a8ef10c500a7 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3646,6 +3646,14 @@ def : MutualExclusions<[Owner, Pointer]>; // Microsoft-related attributes +def MSConstexpr : InheritableAttr { + let LangOpts = [MicrosoftExt]; + let Spellings = [CXX11<"msvc", "constexpr">]; + let Subjects = SubjectList<[Function, ReturnStmt], ErrorDiag, + "functions and return statements">; + let Documentation = [MSConstexprDocs]; +} + def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 88f7c65e6e847b..9dc6a909f07d09 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3657,6 +3657,21 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated as if it were a ``constexpr`` function +if it is evaluated in a constant context of ``[[msvc::constexpr]] return`` statement. +Otherwise, it is treated as a regular function. + +Semantics of this attribute is enabled only under MSVC compatibility +(``-fms-compatibility-version``) 19.33 and later. + }]; +} + def MSNoVTableDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ea08fa84d022cd..28d95ca9b13893 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2884,6 +2884,8 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_cannot_be_applied : Error< + "attribute 'msvc::constexpr' cannot be applied to the %select{constexpr|consteval|virtual}0 function %1">; // C++20 function try blocks in constexpr def ext_constexpr_function_try_block_cxx20 : ExtWarn< diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 2d167dd2bdf128..c4979b9a38c0cf 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -152,6 +152,7 @@ class LangOptions : public LangOptionsBase { MSVC2019 = 1920, MSVC2019_5 = 1925, MSVC2019_8 = 1928, +MSVC2022_3 = 1933, }; enum SYCLMajorVersion { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 986302e1fd225f..90cc0b84f0439c 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -641,6 +641,10 @@ namespace { return false; } +/// Whether we're in a context where [[msvc::constexpr]] evaluation is +/// permitted. See MSConstexprDocs for description of permitted contexts. +bool CanEvalMSConstexpr = false; + private: APValue &createLocal(APValue::LValueBase Base, const void *Key, QualType T,
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: > Also, please don't 'force-push', just push an additional commit to your > review. It erases history and makes reviewing it about 3x harder since > history/context gets lost. Sorry. I did this, because I am used to such workflow and reviewing [range-diff](https://github.com/llvm/llvm-project/compare/c700d21baf395aafbeea88778d13188650ed0c21..1af977ae49616ee00a64f50302f4cd88f9a51881); but to make it work one have to follow strict rule of pushing changes and rebased branch separately (which I failed to do previous time). 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -235,6 +235,7 @@ Non-comprehensive list of changes in this release except that it returns the size of a type ignoring tail padding. * ``__builtin_classify_type()`` now classifies ``_BitInt`` values as the return value ``18`` and vector types as return value ``19``, to match GCC 14's behavior. +* Since MSVC 19.33 added undocumented attribute ``[[msvc::constexpr]]``, this release adds the attribute as well. RIscRIpt wrote: Added back. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -5546,11 +5563,14 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, case Stmt::LabelStmtClass: return EvaluateStmt(Result, Info, cast(S)->getSubStmt(), Case); - case Stmt::AttributedStmtClass: -// As a general principle, C++11 attributes can be ignored without -// any semantic impact. -return EvaluateStmt(Result, Info, cast(S)->getSubStmt(), -Case); + case Stmt::AttributedStmtClass: { +const auto *AS = cast(S); +const auto *SS = AS->getSubStmt(); +MSConstexprContextRAII msConstexprContext( RIscRIpt wrote: Adjusted manually. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -3657,6 +3657,21 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated as if it were a ``constexpr`` function +if it is evaluated in a constant context of ``[[msvc::constexpr]] return`` statement. +Otherwise, it is treated as a regular function. + +Semantics of this attribute is enabled only under MSVC compatibility RIscRIpt wrote: Adjusted manually. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; RIscRIpt wrote: tl;dr afterall I would keep it as-is. Sorry, I overestimated this possibility. > attribute 'msvc::constexpr' cannot be applied to the virtual function %1 This could be replaced with existing diagnostic ``` def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; ``` However, two other variants of this new diagnostic: > attribute 'msvc::constexpr' cannot be applied to the constexpr function %1 > attribute 'msvc::constexpr' cannot be applied to the consteval function %1 Are not easily replaceable. The most similar diagnostic I was able to find was: ``` def err_invalid_decl_spec_combination : Error< "cannot combine with previous '%0' declaration specifier">; ``` But, using this diagnostic, warnings are not consistent: ``` /home/richard/projects/llvm-project/clang/test/SemaCXX/ms-constexpr-invalid.cpp:10:3: error: cannot combine with previous 'constexpr' declaration specifier 10 | [[msvc::constexpr]] constexpr void f1() {} | ^~~~ ``` `constexpr` comes after `[[msvc::constexpr]]`, but the message implies that `constexpr` came first. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: Thank you! 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: I don't have write access, but I believe it is ready to be merged. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: Suggested commit message: ``` Add support for 'msvc::constexpr' C++11 attribute This commit adds support for MSVC-specific C++11-style attribute `[[msvc::constexpr]]`, which was added in MSVC 14.33. The semantics of this attribute is enabled only under MSVC compatibility (`-fms-compatibility-version`) 14.33 and higher. Additionally, default value of `_MSC_VER` was raised to 1433. The current implementation misses support of: - `[[msvc::constexpr]]` constructors (see #72149); at the time of implementation such support required unreasonable amount of changes in Clang. - `[[msvc::constexpr]] return ::new` (constexpr placement new) from non-std namespace (see #74924). Relevant to: #57696 ``` 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify=supported %s RIscRIpt wrote: We can just remove `__cdecl` altogether. I put it there to replicate Microsoft's STL. MSVC accepts that test case without `__cdecl` too. Regarding other compiler error, it was fixed in 3ec6c72551846b8f4143c8c101a1a6203e85a2aa 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
[clang] [clang] Fix '__cdecl' CC is not supported for this target (PR #74932)
https://github.com/RIscRIpt created https://github.com/llvm/llvm-project/pull/74932 Fixes regression introduced in b3e6ff331925dde24a4707452d657da0fdf7f588 .---command stderr | error: 'supported-warning' diagnostics seen but not expected: | File C:\buildbot\as-builder-1\x-armv7l\llvm-project\clang\test\SemaCXX\ms-constexpr-new.cpp Line 7: '__cdecl' calling convention is not supported for this target | 1 error generated. `- >From e16ec1411f7f813f7c1b60fd9671db116b083d02 Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Sat, 9 Dec 2023 15:44:54 +0200 Subject: [PATCH] [clang] Fix '__cdecl' CC is not supported for this target Fixes regression introduced in b3e6ff331925dde24a4707452d657da0fdf7f588 .---command stderr | error: 'supported-warning' diagnostics seen but not expected: | File C:\buildbot\as-builder-1\x-armv7l\llvm-project\clang\test\SemaCXX\ms-constexpr-new.cpp Line 7: '__cdecl' calling convention is not supported for this target | 1 error generated. `- --- clang/test/SemaCXX/ms-constexpr-new.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/ms-constexpr-new.cpp b/clang/test/SemaCXX/ms-constexpr-new.cpp index 05ee5c5b4e154a..30567740b2ecbb 100644 --- a/clang/test/SemaCXX/ms-constexpr-new.cpp +++ b/clang/test/SemaCXX/ms-constexpr-new.cpp @@ -4,7 +4,7 @@ [[nodiscard]] [[msvc::constexpr]] // unsupported-warning {{unknown attribute 'constexpr' ignored}} -inline void* __cdecl operator new(decltype(sizeof(void*)), void* p) noexcept { return p; } +inline void* operator new(decltype(sizeof(void*)), void* p) noexcept { return p; } namespace std { constexpr int* construct_at(int* p, int v) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -verify=supported %s RIscRIpt wrote: Opened #74932. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt created https://github.com/llvm/llvm-project/pull/71300 As per agreement with @AaronBallman and @erichkeane, I am re-opening this patch here. The current version of the patch has undergone numerous revisions before it became the version I am sending to GitHub. Below you can find a summary of the history of changes. The full history of all comments (excluding code-inline comments) is available in this file: [msvc-constexpr-D134475-comments.md](https://github.com/llvm/llvm-project/files/13257930/msvc-constexpr-D134475-comments.md) --- Initially I submitted this patch to make `[[msvc::constexpr]]` visible in the AST, with no semantics, and no tests at all. @AaronBallman has told me that you typically don't accept such patches, so I started figuring out semantics of `[[msvc::constexpr]]`. At first I tried to kind of reverse-engineer it myself, I made several observations, some of them were incorrect. Later, @cpplearner noted: > 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`. Additionally I asked MSVC team to comment about `[[msvc::constexpr]]`. Cody Miller from Microsoft has shared semantics of `[[msvc::constexpr]]` [here](https://developercommunity.visualstudio.com/t/msvc::constexpr-specification/10259132). Further testing and experiments revealed that, unfortunately not all of his points were correct. After some trials and errors, I came up with the following definition of semantics for `[[msvc::constexpr]]` The `[[msvc::constexpr]]` attribute can be applied only to a function definition or a `return` statement. It does not impact function declarations. A `[[msvc::constexpr]]` function cannot be `constexpr` or `consteval`. A `[[msvc::constexpr]]` function is treated in the same way as a `constexpr` function if it is evaluated in a constant context of `[[msvc::constexpr]] return` statement. Otherwise, it is treated as a regular function. This doc-note was added to `MSConstexprDocs`. As per this definition, we need to be able to track whether current invocation of `[[msvc::constexpr]]` function comes from `[[msvc::constexpr]] return` statement, which in turn comes from a constant evaluation context (i.e. a `constexpr` function). Thus I went with the approach, which I saw being used in some other cases: a RAII helper (`MSConstexprContextRAII`), and a `bool` flag in `CallStackFrame`. >From d27897ade53ab6f983e442f24880260eed26238a Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Thu, 20 Jul 2023 00:18:50 +0300 Subject: [PATCH 1/2] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute Differential Revision: https://reviews.llvm.org/D134475 --- clang/include/clang/Basic/Attr.td | 8 +++ clang/include/clang/Basic/AttrDocs.td | 16 ++ .../clang/Basic/DiagnosticSemaKinds.td| 10 +++- clang/include/clang/Basic/LangOptions.h | 1 + clang/lib/AST/ExprConstant.cpp| 34 +--- clang/lib/Basic/Targets/OSTargets.cpp | 3 ++ clang/lib/Sema/SemaDecl.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 24 + clang/lib/Sema/SemaDeclCXX.cpp| 5 +- clang/lib/Sema/SemaStmtAttr.cpp | 16 ++ clang/test/AST/ms-constexpr.cpp | 28 ++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaCXX/ms-constexpr-invalid.cpp | 52 +++ clang/test/SemaCXX/ms-constexpr-new.cpp | 16 ++ clang/test/SemaCXX/ms-constexpr.cpp | 37 + 15 files changed, 245 insertions(+), 10 deletions(-) create mode 100644 clang/test/AST/ms-constexpr.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-invalid.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-new.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 60b54c155e5..771ac5575e25d8c 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3602,6 +3602,14 @@ def : MutualExclusions<[Owner, Pointer]>; // Microsoft-related attributes +def MSConstexpr : InheritableAttr { + let LangOpts = [MicrosoftExt]; + let Spellings = [CXX11<"msvc", "constexpr">]; + let Subjects = SubjectList<[Function, Stmt], ErrorDiag, + "functions and statements">; + let Documentation = [MSConstexprDocs]; +} + def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; di
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: Initially I replicated semantics of `[[msvc::constexpr]]` from MSVC, so that it was possible to use it the same way as in MSVC, even `[[msvc::constexpr]] return ::new` from non-std namespace. E.g. https://godbolt.org/z/7eKh5Envz ```cpp // RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -ast-dump %s | FileCheck %s // CHECK: used operator new // CHECK: MSConstexprAttr 0x{{[0-9a-f]+}} [[nodiscard]] [[msvc::constexpr]] inline void* __cdecl operator new(decltype(sizeof(void*)), void* p) noexcept { return p; } // CHECK: used constexpr construct_at // CHECK: AttributedStmt 0x{{[0-9a-f]+}} // CHECK-NEXT: MSConstexprAttr 0x{{[0-9a-f]+}} // CHECK-NEXT: ReturnStmt 0x{{[0-9a-f]+}} constexpr int* construct_at(int* p, int v) { [[msvc::constexpr]] return ::new (p) int(v); } constexpr bool check_construct_at() { int x; return *construct_at(&x, 42) == 42; } static_assert(check_construct_at()); ``` However @rsmith raised a concern over changes in `PointerExprEvaluator::VisitCXXNewExpr`: ```diff bool IsNothrow = false; bool IsPlacement = false; + bool IsMSConstexpr = Info.CurrentCall->CanEvalMSConstexpr && + OperatorNew->hasAttr(); if (OperatorNew->isReservedGlobalPlacementOperator() && - Info.CurrentCall->isStdFunction() && !E->isArray()) { + (Info.CurrentCall->isStdFunction() || IsMSConstexpr) && !E->isArray()) { ``` > Do we really need this change? Was our existing check of whether the caller > is in namespace std not sufficient for MS' standard library? I'd strongly > prefer not to have a documented, user-visible attribute that gives permission > to use placement new directly. If I could choose, I would opt to fully replicate the behavior of MSVC. However, I also acknowledge the concerns that have been raised. @AaronBallman, @erichkeane, any 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: Discussion initiated by @AaronBallman of one of important design decisions, which was forgotten (?): > @AaronBallman: > 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. > @RIscRIpt: > IMO, this attribute is a clearly Microsoft's extension, thus it should be > available only when `-fms-extensions` are enabled. Note: in the current implementation I enable `[[msvc::constexpr]]` only under `-fms-compatibility -fms-compatibility-version=19.33`, (MSVC 19.33), where this attribute has first appeared. 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt edited 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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
@@ -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
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
https://github.com/RIscRIpt updated https://github.com/llvm/llvm-project/pull/71300 >From 65c306e94e9b749ef0d38ef709ddb8b23dac987a Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Thu, 20 Jul 2023 00:18:50 +0300 Subject: [PATCH 1/2] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute Differential Revision: https://reviews.llvm.org/D134475 --- clang/include/clang/Basic/Attr.td | 8 +++ clang/include/clang/Basic/AttrDocs.td | 16 ++ .../clang/Basic/DiagnosticSemaKinds.td| 10 +++- clang/include/clang/Basic/LangOptions.h | 1 + clang/lib/AST/ExprConstant.cpp| 34 +--- clang/lib/Basic/Targets/OSTargets.cpp | 3 ++ clang/lib/Sema/SemaDecl.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 24 + clang/lib/Sema/SemaDeclCXX.cpp| 5 +- clang/lib/Sema/SemaStmtAttr.cpp | 16 ++ clang/test/AST/ms-constexpr.cpp | 28 ++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaCXX/ms-constexpr-invalid.cpp | 52 +++ clang/test/SemaCXX/ms-constexpr-new.cpp | 16 ++ clang/test/SemaCXX/ms-constexpr.cpp | 37 + 15 files changed, 245 insertions(+), 10 deletions(-) create mode 100644 clang/test/AST/ms-constexpr.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-invalid.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr-new.cpp create mode 100644 clang/test/SemaCXX/ms-constexpr.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 03ed6accf700c4e6..08730e4dfd67feca 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3638,6 +3638,14 @@ def : MutualExclusions<[Owner, Pointer]>; // Microsoft-related attributes +def MSConstexpr : InheritableAttr { + let LangOpts = [MicrosoftExt]; + let Spellings = [CXX11<"msvc", "constexpr">]; + let Subjects = SubjectList<[Function, Stmt], ErrorDiag, + "functions and statements">; + let Documentation = [MSConstexprDocs]; +} + def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index be74535e28d8a60d..709a376bec9fbe95 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3612,6 +3612,22 @@ an error: }]; } +def MSConstexprDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[msvc::constexpr]]`` attribute can be applied only to a function +definition or a ``return`` statement. It does not impact function declarations. +A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``. +A ``[[msvc::constexpr]]`` function is treated in the same way as a ``constexpr`` +function if it is evaluated in a constant context of +``[[msvc::constexpr]] return`` statement. +Otherwise, it is treated as a regular function. + +Semantics of this attribute is enabled only under MSVC compatibility +(``-fms-compatibility-version``) 19.33 and later. + }]; +} + def MSNoVTableDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6894e22da34e0c74..43349cdfaea75c9a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2861,8 +2861,8 @@ def warn_cxx17_compat_constexpr_local_var_no_init : Warning< "is incompatible with C++ standards before C++20">, InGroup, DefaultIgnore; def ext_constexpr_function_never_constant_expr : ExtWarn< - "%select{constexpr|consteval}1 %select{function|constructor}0 never produces a " - "constant expression">, InGroup>, DefaultError; + "%select{constexpr|consteval|[[msvc::constexpr]]}1 %select{function|constructor}0 " + "never produces a constant expression">, InGroup>, DefaultError; def err_attr_cond_never_constant_expr : Error< "%0 attribute expression never produces a constant expression">; def err_diagnose_if_invalid_diagnostic_type : Error< @@ -2884,6 +2884,12 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< InGroup, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; +def err_ms_constexpr_not_distinct : Error< + "[[msvc::constexpr]] cannot be applied to a %select{constexpr|consteval}0 function %1">; +def err_ms_constexpr_virtual : Error<"virtual function cannot be [[msvc::constexpr]]">; +def warn_ms_constexpr_no_effect : Warning< + "[[msvc::constexpr]] has effect only on function definitions and return statements">, + InGroup; // C++20 function try blocks in constexpr def ext_constexpr_function_try_block_cxx20 : ExtWarn< diff --git a/clang/include/clan
[clang] [clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (PR #71300)
RIscRIpt wrote: Rebased onto main, resolved conflicts, re-run lit locally. Please let me know if I could speed-up review in any way. 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
[clang] [Clang] allow [[msvc::constexpr]] usage outside the std namespace (PR #119153)
RIscRIpt wrote: > allow [[msvc::constexpr]] usage outside the std namespace By the way, to be precisely correct, these changes actually allow usage of "placement new" in `[[msvc::constexpr]]` context outside of the std namespace. https://github.com/llvm/llvm-project/pull/119153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] allow usage of placement new operator in [[msvc::constexpr]] context outside of the std namespace (PR #119153)
https://github.com/RIscRIpt approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/119153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] allow [[msvc::constexpr]] usage outside the std namespace (PR #119153)
RIscRIpt wrote: Instead of adding this new test, could you please modify behavior of existing test: [`clang/test/SemaCXX/ms-constexpr-new.cpp`](https://github.com/llvm/llvm-project/pull/71300/files#diff-b0e33c7c54dd10b988b2badcc60be091e69ff3aeaf86c95cb2bb9bec14ac376f). https://github.com/llvm/llvm-project/pull/119153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] allow [[msvc::constexpr]] usage outside the std namespace (PR #119153)
https://github.com/RIscRIpt requested changes to this pull request. https://github.com/llvm/llvm-project/pull/119153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] allow [[msvc::constexpr]] usage outside the std namespace (PR #119153)
RIscRIpt wrote: I don't think so. Ah, I forgot I previously added `clang/test/AST/ms-constexpr.cpp`, so having your new `ms-constexpr-new.cpp` makes sense (sorry for confusion). But I still would like to see a test in `clang/test/SemaCXX/ms-constexpr-new.cpp` that placement new can be called outside of `std` namespace (in non c++26 mode) when used in `[[msvc::constexpr]]` context. https://github.com/llvm/llvm-project/pull/119153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] allow [[msvc::constexpr]] usage outside the std namespace (PR #119153)
https://github.com/RIscRIpt edited https://github.com/llvm/llvm-project/pull/119153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix SemaCXX/msvc-pragma-function-no-builtin-attr.cpp test (PR #119873)
DzenIsRich wrote: > I'm seeing this on Linux: ... Yes, the same problem. It should be fixed now. https://github.com/llvm/llvm-project/pull/119873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix SemaCXX/msvc-pragma-function-no-builtin-attr.cpp test (PR #119873)
RIscRIpt wrote: This should fix https://lab.llvm.org/buildbot/#/builders/190/builds/11300 I am compiling clang locally to verify that there would be no other problems with the test on macOS. > I suppose this is the reason check-clang fails today. Are there other test failures related to 84b0f0145887bbfe49fd4dc85490b14108a72cee ? https://github.com/llvm/llvm-project/pull/119873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix SemaCXX/msvc-pragma-function-no-builtin-attr.cpp test (PR #119873)
RIscRIpt wrote: > I'm seeing this on Linux: ... Yes, the same problem. It should be fixed now. https://github.com/llvm/llvm-project/pull/119873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix SemaCXX/msvc-pragma-function-no-builtin-attr.cpp test (PR #119873)
https://github.com/RIscRIpt approved this pull request. LGTM, this fixes `clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp` on macOS. https://github.com/llvm/llvm-project/pull/119873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix SemaCXX/msvc-pragma-function-no-builtin-attr.cpp test (PR #119873)
https://github.com/RIscRIpt closed https://github.com/llvm/llvm-project/pull/119873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp for x86 (PR #119986)
https://github.com/RIscRIpt closed https://github.com/llvm/llvm-project/pull/119986 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp for x86 (PR #119986)
https://github.com/RIscRIpt created https://github.com/llvm/llvm-project/pull/119986 Fix test failure from #119719 84b0f0145887bbfe49fd4dc85490b14108a72cee Closes #119979 >From 876efed487603b450c56cd4c282449f5bfef52ad Mon Sep 17 00:00:00 2001 From: Richard Dzenis Date: Sat, 14 Dec 2024 23:32:04 +0200 Subject: [PATCH] Fix clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp for x86 Fix test failure from #119719 84b0f0145887bbfe49fd4dc85490b14108a72cee --- clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp b/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp index 066c66884e33c1..7262ffd079a92a 100644 --- a/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp +++ b/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp @@ -18,10 +18,10 @@ int bar() { struct A { int foo() = delete; -// CHECK: CXXMethodDecl {{.*}} foo 'int ()' delete +// CHECK: CXXMethodDecl {{.*}} foo {{.*}} delete // CHECK-NOT: NoBuiltinAttr A() = default; -// CHECK: CXXConstructorDecl {{.*}} A 'void ()' default +// CHECK: CXXConstructorDecl {{.*}} A {{.*}} default // CHECK-NOT: NoBuiltinAttr }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp for x86 (PR #119986)
RIscRIpt wrote: I reproduced the problem locally by adding `-m32` flag to `%clang_cl`. Changes in this PR fix the test failure. https://github.com/llvm/llvm-project/pull/119986 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits