[llvm] 44ff94e - [Diagnostics] Return rvalue reference from temporary argument (#127400)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 12 18:07:10 PDT 2025


Author: Jonas Hahnfeld
Date: 2025-03-13T08:07:07+07:00
New Revision: 44ff94e99e0380d520d7e9803100044867ab08db

URL: https://github.com/llvm/llvm-project/commit/44ff94e99e0380d520d7e9803100044867ab08db
DIFF: https://github.com/llvm/llvm-project/commit/44ff94e99e0380d520d7e9803100044867ab08db.diff

LOG: [Diagnostics] Return rvalue reference from temporary argument (#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

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
    llvm/include/llvm/IR/DiagnosticInfo.h
    llvm/lib/Analysis/InlineAdvisor.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b14e55782adb..64e6442bb92f8 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -69,6 +69,9 @@ 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(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..779c88993b71c 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 {
 
@@ -612,82 +613,47 @@ class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
 /// common base class.  This allows returning the result of the insertion
 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
 template <class RemarkT>
-RemarkT &
-operator<<(RemarkT &R,
-           std::enable_if_t<
-               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
-               StringRef>
-               S) {
-  R.insert(S);
-  return R;
-}
-
-/// Also allow r-value for the remark to allow insertion into a
-/// temporarily-constructed remark.
-template <class RemarkT>
-RemarkT &
+decltype(auto)
 operator<<(RemarkT &&R,
-           std::enable_if_t<
-               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
-               StringRef>
+           std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+                                              std::remove_reference_t<RemarkT>>,
+                            StringRef>
                S) {
   R.insert(S);
-  return R;
-}
-
-template <class 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::forward<RemarkT>(R);
 }
 
 template <class RemarkT>
-RemarkT &
+decltype(auto)
 operator<<(RemarkT &&R,
-           std::enable_if_t<
-               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
-               DiagnosticInfoOptimizationBase::Argument>
+           std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+                                              std::remove_reference_t<RemarkT>>,
+                            DiagnosticInfoOptimizationBase::Argument>
                A) {
   R.insert(A);
-  return R;
-}
-
-template <class 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::forward<RemarkT>(R);
 }
 
 template <class RemarkT>
-RemarkT &
+decltype(auto)
 operator<<(RemarkT &&R,
-           std::enable_if_t<
-               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
-               DiagnosticInfoOptimizationBase::setIsVerbose>
+           std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+                                              std::remove_reference_t<RemarkT>>,
+                            DiagnosticInfoOptimizationBase::setIsVerbose>
                V) {
   R.insert(V);
-  return R;
+  return std::forward<RemarkT>(R);
 }
 
 template <class RemarkT>
-RemarkT &
-operator<<(RemarkT &R,
-           std::enable_if_t<
-               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
-               DiagnosticInfoOptimizationBase::setExtraArgs>
+decltype(auto)
+operator<<(RemarkT &&R,
+           std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+                                              std::remove_reference_t<RemarkT>>,
+                            DiagnosticInfoOptimizationBase::setExtraArgs>
                EA) {
   R.insert(EA);
-  return R;
+  return std::forward<RemarkT>(R);
 }
 
 /// Common features for diagnostics dealing with optimization remarks

diff  --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 12553dd446a61..5b2f0479e2b41 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) {
+decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) {
   using namespace ore;
   if (IC.isAlways()) {
     R << "(cost=always)";
@@ -350,7 +350,7 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
   }
   if (const char *Reason = IC.getReason())
     R << ": " << ore::NV("Reason", Reason);
-  return R;
+  return std::forward<RemarkT>(R);
 }
 } // namespace llvm
 


        


More information about the llvm-commits mailing list