aaron.ballman created this revision. aaron.ballman added reviewers: erichkeane, rsmith, clang-language-wg. Herald added a project: All. aaron.ballman requested review of this revision. Herald added a project: clang.
Previously, we would instantiate the UDL by marking the function as referenced and potentially binding to a temporary; this skipped transforming the call when the UDL was dependent on a template parameter. Now, we defer all the work to instantiating the call expression for the UDL. This ensures that constant evaluation occurs at compile time rather than deferring until runtime. Fixes Issue 54578. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122586 Files: clang/docs/ReleaseNotes.rst clang/lib/Sema/TreeTransform.h clang/test/CodeGenCXX/cxx20-consteval-crash.cpp clang/test/SemaCXX/cxx2a-consteval.cpp Index: clang/test/SemaCXX/cxx2a-consteval.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-consteval.cpp +++ clang/test/SemaCXX/cxx2a-consteval.cpp @@ -721,3 +721,27 @@ expected-note {{subobject of type 'int' is not initialized}} } // namespace NamespaceScopeConsteval + +namespace Issue54578 { +// We expect the user-defined literal to be resovled entirely at compile time +// despite being instantiated through a template. +inline consteval unsigned char operator""_UC(const unsigned long long n) { + return static_cast<unsigned char>(n); +} + +inline constexpr char f1(const auto octet) { + return 4_UC; +} + +template <typename Ty> +inline constexpr char f2(const Ty octet) { + return 4_UC; +} + +void test() { + static_assert(f1('a') == 4); + static_assert(f2('a') == 4); + constexpr int c = f1('a') + f2('a'); + static_assert(c == 8); +} +} Index: clang/test/CodeGenCXX/cxx20-consteval-crash.cpp =================================================================== --- clang/test/CodeGenCXX/cxx20-consteval-crash.cpp +++ clang/test/CodeGenCXX/cxx20-consteval-crash.cpp @@ -24,3 +24,29 @@ // CHECK: ret void // CHECK: } } + +namespace Issue54578 { +inline consteval unsigned char operator""_UC(const unsigned long long n) { + return static_cast<unsigned char>(n); +} + +inline constexpr char f1(const auto octet) { + return 4_UC; +} + +template <typename Ty> +inline constexpr char f2(const Ty octet) { + return 4_UC; +} + +int foo() { + return f1('a') + f2('a'); +} + +// CHECK-NOT: define{{.*}} zeroext i8 @_ZN10Issue54578li3_UCEy +// CHECK: define{{.*}} i32 @_ZN10Issue545783fooEv( +// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f1IcEEcT_( +// CHECK: ret i8 4 +// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f2IcEEcT_( +// CHECK: ret i8 4 +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -10513,9 +10513,7 @@ template<typename Derived> ExprResult TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) { - if (FunctionDecl *FD = E->getDirectCallee()) - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), FD); - return SemaRef.MaybeBindToTemporary(E); + return TransformCallExpr(E); } template<typename Derived> Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -189,6 +189,9 @@ ^^^^^^^^^^^^^^^^^^^^^ - Diagnose consteval and constexpr issues that happen at namespace scope. This partially addresses `Issue 51593 <https://github.com/llvm/llvm-project/issues/51593>`_. +- No longer attempt to evaluate a consteval UDL function call at runtime when + it is called through a template instantiation. This fixes + `Issue 54578 <https://github.com/llvm/llvm-project/issues/54578>`_. C++2b Feature Support ^^^^^^^^^^^^^^^^^^^^^
Index: clang/test/SemaCXX/cxx2a-consteval.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-consteval.cpp +++ clang/test/SemaCXX/cxx2a-consteval.cpp @@ -721,3 +721,27 @@ expected-note {{subobject of type 'int' is not initialized}} } // namespace NamespaceScopeConsteval + +namespace Issue54578 { +// We expect the user-defined literal to be resovled entirely at compile time +// despite being instantiated through a template. +inline consteval unsigned char operator""_UC(const unsigned long long n) { + return static_cast<unsigned char>(n); +} + +inline constexpr char f1(const auto octet) { + return 4_UC; +} + +template <typename Ty> +inline constexpr char f2(const Ty octet) { + return 4_UC; +} + +void test() { + static_assert(f1('a') == 4); + static_assert(f2('a') == 4); + constexpr int c = f1('a') + f2('a'); + static_assert(c == 8); +} +} Index: clang/test/CodeGenCXX/cxx20-consteval-crash.cpp =================================================================== --- clang/test/CodeGenCXX/cxx20-consteval-crash.cpp +++ clang/test/CodeGenCXX/cxx20-consteval-crash.cpp @@ -24,3 +24,29 @@ // CHECK: ret void // CHECK: } } + +namespace Issue54578 { +inline consteval unsigned char operator""_UC(const unsigned long long n) { + return static_cast<unsigned char>(n); +} + +inline constexpr char f1(const auto octet) { + return 4_UC; +} + +template <typename Ty> +inline constexpr char f2(const Ty octet) { + return 4_UC; +} + +int foo() { + return f1('a') + f2('a'); +} + +// CHECK-NOT: define{{.*}} zeroext i8 @_ZN10Issue54578li3_UCEy +// CHECK: define{{.*}} i32 @_ZN10Issue545783fooEv( +// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f1IcEEcT_( +// CHECK: ret i8 4 +// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f2IcEEcT_( +// CHECK: ret i8 4 +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -10513,9 +10513,7 @@ template<typename Derived> ExprResult TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) { - if (FunctionDecl *FD = E->getDirectCallee()) - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), FD); - return SemaRef.MaybeBindToTemporary(E); + return TransformCallExpr(E); } template<typename Derived> Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -189,6 +189,9 @@ ^^^^^^^^^^^^^^^^^^^^^ - Diagnose consteval and constexpr issues that happen at namespace scope. This partially addresses `Issue 51593 <https://github.com/llvm/llvm-project/issues/51593>`_. +- No longer attempt to evaluate a consteval UDL function call at runtime when + it is called through a template instantiation. This fixes + `Issue 54578 <https://github.com/llvm/llvm-project/issues/54578>`_. C++2b Feature Support ^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits