RIscRIpt added a comment. > TODO: I think, I'll need to read more about constexpr for functions in > standard (and LLVM code), to add relevant restrictions here.
In the standard I was able to find the following paragraphs about `constexpr`: 1. Neither constructor nor destructor can be constexpr if the class has some virtual base class; this holds for `[[msvc::constexpr]]` in MSVC 14.33 2. `constexpr` is not a part of function signature, so same non-constexpr function cannot be defined. The same holds for C++11 attributes, and `[[msvc::constexpr]]` in MSVC 14.33 I will add two relevant tests in `msvc-attrs-invalid.cpp` Regarding LLVM code, I made the following observations: - `FunctionDecl::isConstexprSpecified()` is mostly used for printing code, in other words, to check that the function is `constexpr` (and not `consteval`). - `FunctionDecl::getConstexprKind()` is used by: - `ASTImporter.cpp` - seems that, it should take care of attributes independently from the `getConstexprKind()` - `ASTWriterDecl.cpp` - seems that, it should take care of attributes independently from the `getConstexprKind()` - `SemaDecl.cpp` / `SemaDeclCXX.cpp` - checks that re-declaration was not performed with different constexpr specifier. MSVC and clang with current implementation allows re-declaration with different attributes (there are tests with `f2-f5` in `msvc-attrs.cpp`) - `SemaDeclCXX` - enables C++ constexpr constructor inheritance - problem - my current implementation supports it, whereas MSVC doesn't: // Check '[[msvc::constexpr]]' is not taken into account during constructor inheritance struct s2 { [[msvc::constexpr]] s2() {} constexpr operator bool() { return false; }; }; struct s3 : s2 { constexpr operator bool() { return true; }; }; static_assert(s3()); // MSVC: C2131: expression did not evaluate to a constant static_assert(s3()); // clang with my patch: OK - `SemaTemplate.cpp` - enables C++ template re-specialization with different constexpr specifier, not a problem, because we are allowed to do the same with attributes (don't we?) - `SemaTemplateInstantiateDecl.cpp` (`TemplateDeclInstantiator`) - enables C++ template instantiation with same constexpr specifier template<typename T> struct s1 { [[msvc::constexpr]] s1() {} constexpr operator bool() { return true; }; }; static_assert(s1<void>()); // MSVC: C2131: expression did not evaluate to a constant static_assert(s1<void>()); // clang with my patch: OK - `TreeTransform.h` - code is related to lambdas - out-of-scope of the current patch. Regarding `MSVC:C2131` I found one more problem: [[msvc::constexpr]] int C() { return 0; } constexpr int V = C(); // MSVC: C2131: expression did not evaluate to a constant constexpr int W = C(); // clang with my patch: OK I am starting to question my patch - does LLVM really need it, if 1. There's no documentation for `[[msvc::constexpr]]` 2. The trivial implementation makes it an alias, but the semantic behavior is different - we could fix that, but there are lots of things to check @aaron.ballman WDYT? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134475/new/ https://reviews.llvm.org/D134475 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits