[llvm] Return rvalue reference from temporary argument (PR #127400)

Jonas Hahnfeld via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 16 07:09:09 PST 2025


https://github.com/hahnjo created https://github.com/llvm/llvm-project/pull/127400

This fixes compilation issues with GCC and C++23:
```
error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&' to an rvalue of type
'llvm::OptimizationRemarkMissed'
```

Closes #105778

>From e0e37c9233ae977f73bfc2793a2a2172decbc828 Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <hahnjo at hahnjo.de>
Date: Sun, 16 Feb 2025 14:54:15 +0100
Subject: [PATCH] Return rvalue reference from temporary argument

This fixes compilation issues with GCC and C++23:
```
error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&' to an rvalue of type
'llvm::OptimizationRemarkMissed'
```

Closes #105778
---
 .../llvm/Analysis/OptimizationRemarkEmitter.h |  5 ++++
 llvm/include/llvm/IR/DiagnosticInfo.h         | 24 ++++++++++++++-----
 llvm/lib/Analysis/InlineAdvisor.cpp           |  8 ++++++-
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b14e55782adb..2640bb9194010 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -69,6 +69,11 @@ class OptimizationRemarkEmitter {
   /// Output the remark via the diagnostic handler and to the
   /// optimization record file.
   void emit(DiagnosticInfoOptimizationBase &OptDiag);
+  /// Also allow r-value for OptDiag to allow emitting a temporarily-constructed
+  /// diagnostic.
+  void emit(DiagnosticInfoOptimizationBase &&OptDiag) {
+    emit(static_cast<DiagnosticInfoOptimizationBase &>(OptDiag));
+  }
 
   /// Take a lambda that returns a remark which will be emitted.  Second
   /// argument is only used to restrict this to functions.
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 694785317af04..1e26cfdd17b5f 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -30,6 +30,7 @@
 #include <iterator>
 #include <optional>
 #include <string>
+#include <utility>
 
 namespace llvm {
 
@@ -625,14 +626,14 @@ operator<<(RemarkT &R,
 /// Also allow r-value for the remark to allow insertion into a
 /// temporarily-constructed remark.
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                StringRef>
                S) {
   R.insert(S);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -647,14 +648,14 @@ operator<<(RemarkT &R,
 }
 
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                DiagnosticInfoOptimizationBase::Argument>
                A) {
   R.insert(A);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -669,14 +670,14 @@ operator<<(RemarkT &R,
 }
 
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                DiagnosticInfoOptimizationBase::setIsVerbose>
                V) {
   R.insert(V);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -690,6 +691,17 @@ operator<<(RemarkT &R,
   return R;
 }
 
+template <class RemarkT>
+RemarkT &&
+operator<<(RemarkT &&R,
+           std::enable_if_t<
+               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+               DiagnosticInfoOptimizationBase::setExtraArgs>
+               EA) {
+  R.insert(EA);
+  return std::move(R);
+}
+
 /// Common features for diagnostics dealing with optimization remarks
 /// that are used by IR passes.
 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 12553dd446a61..2041610cd5ee9 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -338,7 +338,7 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
 }
 
 template <class RemarkT>
-RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
+RemarkT &operator<<(RemarkT &R, const InlineCost &IC) {
   using namespace ore;
   if (IC.isAlways()) {
     R << "(cost=always)";
@@ -352,6 +352,12 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
     R << ": " << ore::NV("Reason", Reason);
   return R;
 }
+
+template <class RemarkT>
+RemarkT &&operator<<(RemarkT &&R, const InlineCost &IC) {
+  static_cast<RemarkT &>(R) << IC;
+  return std::move(R);
+}
 } // namespace llvm
 
 std::string llvm::inlineCostStr(const InlineCost &IC) {



More information about the llvm-commits mailing list