tree e = expr;
while (handled_component_p (e))
e = TREE_OPERAND (e, 0);
- if (!reference_like_class_p (TREE_TYPE (e)))
+ tree type = TREE_TYPE (e);
+ /* If the temporary represents a lambda, we don't really know
+ what's going on here. */
+ if (!reference_like_class_p (type) && !LAMBDA_TYPE_P (type))
return expr;
}
initializing this reference parameter. */
if (do_warn_dangling_reference (arg, /*arg_p=*/true))
return expr;
- /* Don't warn about member function like:
+ /* Don't warn about member functions like:
std::any a(...);
S& s = a.emplace<S>({0}, 0);
- which constructs a new object and returns a reference to it, but
+ which construct a new object and return a reference to it, but
we still want to detect:
struct S { const S& self () { return *this; } };
const S& s = S().self();
--- /dev/null
+// PR c++/113256
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wdangling-reference" }
+
+#include <utility>
+#include <cassert>
+
+template<class M, class T, class A> auto bind(M T::* pm, A)
+{
+ return [=]( auto&& x ) -> M const& { return x.*pm; };
+}
+
+template<int I> struct arg {};
+
+arg<1> _1;
+
+int main()
+{
+ std::pair<int, int> pair;
+ int const& x = bind( &std::pair<int, int>::first, _1 )( pair ); // { dg-bogus "dangling reference" }
+ assert( &x == &pair.first );
+}
--- /dev/null
+// PR c++/111607
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wdangling-reference" }
+
+#include <variant>
+
+struct S {
+ constexpr S(int i_) : i(i_) {}
+ S(S const &) = delete;
+ S & operator=(S const &) = delete;
+ S(S &&) = delete;
+ S & operator=(S &&) = delete;
+ int i;
+};
+
+struct A {
+ S s{0};
+};
+
+using V = std::variant<A>;
+
+consteval auto f(V const & v) {
+ auto const & s = std::visit([](auto const & v) -> S const & { return v.s; }, v); // { dg-bogus "dangling reference" }
+ return s.i;
+}
+
+int main() {
+ constexpr V a{std::in_place_type<A>};
+ constexpr auto i = f(a);
+ return i;
+}
--- /dev/null
+// PR c++/109640
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wdangling-reference" }
+
+bool
+fn0 ()
+{
+ int a;
+ int&& i = [](int& r) -> int&& { return static_cast<int&&>(r); }(a); // { dg-bogus "dangling reference" }
+ auto const l = [](int& r) -> int&& { return static_cast<int&&>(r); };
+ int&& j = l(a);
+ return &i == &j;
+}