Fznamznon created this revision. Herald added a project: All. Fznamznon requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Clang used to reject consteval operators if they're used inside a template due to TreeTransform putting two different `DeclRefExpr` expressions for the same reference of the same operator declaration into `ReferenceToConsteval` set. It seems there was an attempt to not rebuild the whole operator that never succeeded, so this patch just removes this attempt and problemating referencing of a `DeclRefExpr` that always ended up discarded. Fixes https://github.com/llvm/llvm-project/issues/62886 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D151553 Files: clang/docs/ReleaseNotes.rst clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/consteval-operators.cpp
Index: clang/test/SemaCXX/consteval-operators.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/consteval-operators.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++2a -emit-llvm-only -Wno-unused-value %s -verify + +// expected-no-diagnostics + +struct A { + consteval A operator+() { return {}; } +}; +consteval A operator~(A) { return {}; } +consteval A operator+(A, A) { return {}; } + +template <class> void f() { + A a; + A b = ~a; + A c = a + a; + A d = +a; +} +template void f<int>(); + +template <class T> void foo() { + T a; + T b = ~a; + T c = a + a; + T d = +a; +} + +template void foo<A>(); + +template <typename DataT> struct B { DataT D; }; + +template <typename DataT> +consteval B<DataT> operator+(B<DataT> lhs, B<DataT> rhs) { + return B<DataT>{lhs.D + rhs.D}; +} + +template <class T> consteval T template_add(T a, T b) { return a + b; } + +consteval B<int> non_template_add(B<int> a, B<int> b) { return a + b; } + +void bar() { + constexpr B<int> a{}; + constexpr B<int> b{}; + auto constexpr c = a + b; +} + +static_assert((template_add(B<int>{7}, B<int>{3})).D == 10); +static_assert((non_template_add(B<int>{7}, B<int>{3})).D == 10); Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -11937,10 +11937,6 @@ llvm_unreachable("not an overloaded operator?"); } - ExprResult Callee = getDerived().TransformExpr(E->getCallee()); - if (Callee.isInvalid()) - return ExprError(); - ExprResult First; if (E->getOperator() == OO_Amp) First = getDerived().TransformAddressOfOperand(E->getArg(0)); @@ -11957,23 +11953,15 @@ return ExprError(); } - if (!getDerived().AlwaysRebuild() && - Callee.get() == E->getCallee() && - First.get() == E->getArg(0) && - (E->getNumArgs() != 2 || Second.get() == E->getArg(1))) - return SemaRef.MaybeBindToTemporary(E); - Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); FPOptionsOverride NewOverrides(E->getFPFeatures()); getSema().CurFPFeatures = NewOverrides.applyOverrides(getSema().getLangOpts()); getSema().FpPragmaStack.CurrentValue = NewOverrides; - return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), - E->getOperatorLoc(), - Callee.get(), - First.get(), - Second.get()); + return getDerived().RebuildCXXOperatorCallExpr( + E->getOperator(), E->getOperatorLoc(), E->getCallee(), First.get(), + Second.get()); } template<typename Derived> Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -455,6 +455,8 @@ - Fix crash when diagnosing default comparison method. (`#62791 <https://github.com/llvm/llvm-project/issues/62791>`_) and (`#62102 <https://github.com/llvm/llvm-project/issues/62102>`_). +- Fix reject-valid when consteval operator appears inside of a template. + (`#62886 <https://github.com/llvm/llvm-project/issues/62886>`_). Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits