if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true)))
{
/* If we know the temporary could not bind to the return type,
- don't warn. This is for scalars only because for classes
- we can't be sure we are not returning its sub-object. */
- if (SCALAR_TYPE_P (TREE_TYPE (arg))
+ don't warn. This is for scalars and empty classes only
+ because for other classes we can't be sure we are not
+ returning its sub-object. */
+ if ((SCALAR_TYPE_P (TREE_TYPE (arg))
+ || is_empty_class (TREE_TYPE (arg)))
&& TYPE_REF_P (rettype)
- && !reference_related_p (TREE_TYPE (arg),
- TREE_TYPE (rettype)))
+ && !reference_related_p (TREE_TYPE (rettype),
+ TREE_TYPE (arg)))
continue;
return expr;
}
// { dg-do compile { target c++20 } }
// { dg-options "-Wdangling-reference" }
-class X { };
-const X x1;
-const X x2;
+class X { int i; };
+const X x1 {};
+const X x2 {};
constexpr bool val () { return true; }
struct ST { static constexpr bool value = true; };
// { dg-do compile { target c++20 } }
// { dg-options "-Wdangling-reference" }
-class X { };
-const X x1;
-const X x2;
+class X { int i; };
+const X x1 {};
+const X x2 {};
template<bool... N>
[[gnu::no_dangling(N)]] const X& get(const int& i); // { dg-error "parameter packs not expanded" }
template <typename T>
struct [[gnu::no_dangling(is_reference_v<T>)]] S {
+ int i;
int &foo (const int &);
};
struct X {
template <typename U1 = T1, typename U2 = T2>
struct [[gnu::no_dangling(is_reference_v<U1> && is_reference_v<U2>)]] Y {
+ int i;
int &foo (const int &);
};
};
using false_type = bool_constant<false>;
struct S {
+ int i;
template<bool B>
[[gnu::no_dangling(B)]] int &foo (const int &);
};
const int& refmax = max(n - 1, n + 1); // { dg-warning "dangling reference" }
struct Y {
+ int i;
operator int&();
operator int&&();
const int& foo(const int&);
// { dg-options "-Wdangling-reference" }
namespace std {
-struct any {};
+struct any { void *p; ~any(); };
template <typename _ValueType> _ValueType any_cast(any &&);
template <typename _Tp> struct remove_reference { using type = _Tp; };
template <typename _Tp> _Tp forward(typename remove_reference<_Tp>::type);
--- /dev/null
+// PR c++/115361
+// { dg-additional-options -Wdangling-reference }
+
+struct B { int i; };
+
+struct A {
+ const int & operator()(const B& b) { return b.i; }
+};
+
+int main()
+{
+ B b = {};
+ const int &r = A()(b);
+}
};
struct F {
+ int i;
G& f();
};