Skip to content

Commit 44ff94e

Browse files
authored
[Diagnostics] Return rvalue reference from temporary argument (llvm#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 llvm#105778
1 parent cb73271 commit 44ff94e

File tree

3 files changed

+27
-58
lines changed

3 files changed

+27
-58
lines changed

llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class OptimizationRemarkEmitter {
6969
/// Output the remark via the diagnostic handler and to the
7070
/// optimization record file.
7171
void emit(DiagnosticInfoOptimizationBase &OptDiag);
72+
/// Also allow r-value for OptDiag to allow emitting a temporarily-constructed
73+
/// diagnostic.
74+
void emit(DiagnosticInfoOptimizationBase &&OptDiag) { emit(OptDiag); }
7275

7376
/// Take a lambda that returns a remark which will be emitted. Second
7477
/// argument is only used to restrict this to functions.

llvm/include/llvm/IR/DiagnosticInfo.h

+22-56
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <iterator>
3131
#include <optional>
3232
#include <string>
33+
#include <utility>
3334

3435
namespace llvm {
3536

@@ -612,82 +613,47 @@ class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
612613
/// common base class. This allows returning the result of the insertion
613614
/// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
614615
template <class RemarkT>
615-
RemarkT &
616-
operator<<(RemarkT &R,
617-
std::enable_if_t<
618-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
619-
StringRef>
620-
S) {
621-
R.insert(S);
622-
return R;
623-
}
624-
625-
/// Also allow r-value for the remark to allow insertion into a
626-
/// temporarily-constructed remark.
627-
template <class RemarkT>
628-
RemarkT &
616+
decltype(auto)
629617
operator<<(RemarkT &&R,
630-
std::enable_if_t<
631-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
632-
StringRef>
618+
std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
619+
std::remove_reference_t<RemarkT>>,
620+
StringRef>
633621
S) {
634622
R.insert(S);
635-
return R;
636-
}
637-
638-
template <class RemarkT>
639-
RemarkT &
640-
operator<<(RemarkT &R,
641-
std::enable_if_t<
642-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
643-
DiagnosticInfoOptimizationBase::Argument>
644-
A) {
645-
R.insert(A);
646-
return R;
623+
return std::forward<RemarkT>(R);
647624
}
648625

649626
template <class RemarkT>
650-
RemarkT &
627+
decltype(auto)
651628
operator<<(RemarkT &&R,
652-
std::enable_if_t<
653-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
654-
DiagnosticInfoOptimizationBase::Argument>
629+
std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
630+
std::remove_reference_t<RemarkT>>,
631+
DiagnosticInfoOptimizationBase::Argument>
655632
A) {
656633
R.insert(A);
657-
return R;
658-
}
659-
660-
template <class RemarkT>
661-
RemarkT &
662-
operator<<(RemarkT &R,
663-
std::enable_if_t<
664-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
665-
DiagnosticInfoOptimizationBase::setIsVerbose>
666-
V) {
667-
R.insert(V);
668-
return R;
634+
return std::forward<RemarkT>(R);
669635
}
670636

671637
template <class RemarkT>
672-
RemarkT &
638+
decltype(auto)
673639
operator<<(RemarkT &&R,
674-
std::enable_if_t<
675-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
676-
DiagnosticInfoOptimizationBase::setIsVerbose>
640+
std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
641+
std::remove_reference_t<RemarkT>>,
642+
DiagnosticInfoOptimizationBase::setIsVerbose>
677643
V) {
678644
R.insert(V);
679-
return R;
645+
return std::forward<RemarkT>(R);
680646
}
681647

682648
template <class RemarkT>
683-
RemarkT &
684-
operator<<(RemarkT &R,
685-
std::enable_if_t<
686-
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
687-
DiagnosticInfoOptimizationBase::setExtraArgs>
649+
decltype(auto)
650+
operator<<(RemarkT &&R,
651+
std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
652+
std::remove_reference_t<RemarkT>>,
653+
DiagnosticInfoOptimizationBase::setExtraArgs>
688654
EA) {
689655
R.insert(EA);
690-
return R;
656+
return std::forward<RemarkT>(R);
691657
}
692658

693659
/// Common features for diagnostics dealing with optimization remarks

llvm/lib/Analysis/InlineAdvisor.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
338338
}
339339

340340
template <class RemarkT>
341-
RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
341+
decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) {
342342
using namespace ore;
343343
if (IC.isAlways()) {
344344
R << "(cost=always)";
@@ -350,7 +350,7 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
350350
}
351351
if (const char *Reason = IC.getReason())
352352
R << ": " << ore::NV("Reason", Reason);
353-
return R;
353+
return std::forward<RemarkT>(R);
354354
}
355355
} // namespace llvm
356356

0 commit comments

Comments
 (0)