aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2024-03-28 21:33:57 -0400
committerJason Merrill <jason@redhat.com>2024-04-01 12:02:50 -0400
commitbba118db3f63cb1e3953a014aa3ac2ad89908950 (patch)
treefddd4650fb13d2db4f9809d98f4b77efb1c195d0
parentd28ea8e5a70474cf9d28bf0c008092c936ad1358 (diff)
downloadgcc-bba118db3f63cb1e3953a014aa3ac2ad89908950.zip
gcc-bba118db3f63cb1e3953a014aa3ac2ad89908950.tar.gz
gcc-bba118db3f63cb1e3953a014aa3ac2ad89908950.tar.bz2
c++: C++26 returning reference to temporary
P2748R5 makes it ill-formed to return a reference to temporary in C++26; implementing this is a simple matter of changing the existing warning to a permerror. For most of the tests I just changed dg-warning to dg-message to accept both; I test the specific diagnostic type in Wreturn-local-addr-5.C. gcc/cp/ChangeLog: * typeck.cc (maybe_warn_about_returning_address_of_local): Permerror in C++26. gcc/testsuite/ChangeLog: * g++.dg/conversion/pr16333.C: Change dg-warning to dg-message. * g++.dg/cpp0x/constexpr-48324.C * g++.dg/other/pr94326.C * g++.dg/warn/Wreturn-local-addr-2.C * g++.old-deja/g++.jason/warning8.C: Likewise. * g++.dg/cpp1y/auto-fn6.C: Check that others don't complain. * g++.dg/warn/Wreturn-local-addr-5.C: Expect error in C++26.
-rw-r--r--gcc/cp/typeck.cc6
-rw-r--r--gcc/testsuite/g++.dg/conversion/pr16333.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-48324.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/auto-fn6.C8
-rw-r--r--gcc/testsuite/g++.dg/other/pr94326.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/warning8.C2
8 files changed, 16 insertions, 13 deletions
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index f5a0a22..88ed38e 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -10626,8 +10626,10 @@ maybe_warn_about_returning_address_of_local (tree retval, location_t loc)
|| TREE_CODE (whats_returned) == TARGET_EXPR)
{
if (TYPE_REF_P (valtype))
- warning_at (loc, OPT_Wreturn_local_addr,
- "returning reference to temporary");
+ /* P2748 made this an error in C++26. */
+ emit_diagnostic (cxx_dialect >= cxx26 ? DK_PERMERROR : DK_WARNING,
+ loc, OPT_Wreturn_local_addr,
+ "returning reference to temporary");
else if (TYPE_PTR_P (valtype))
warning_at (loc, OPT_Wreturn_local_addr,
"returning pointer to temporary");
diff --git a/gcc/testsuite/g++.dg/conversion/pr16333.C b/gcc/testsuite/g++.dg/conversion/pr16333.C
index a00bc5c..d004930 100644
--- a/gcc/testsuite/g++.dg/conversion/pr16333.C
+++ b/gcc/testsuite/g++.dg/conversion/pr16333.C
@@ -6,5 +6,5 @@ struct X {
int a[3];
X foo1 () { return a; }
-const X &foo2 () { return a; } // { dg-warning "returning reference to temporary" }
+const X &foo2 () { return a; } // { dg-message "returning reference to temporary" }
X &foo3 () { return a; } // { dg-error "cannot bind non-const lvalue ref" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-48324.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-48324.C
index 37ed0e1..f53fd4d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-48324.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-48324.C
@@ -7,7 +7,7 @@ struct S {
};
constexpr const int& to_ref(int i) {
- return S(i).val; // { dg-warning "reference to temporary" }
+ return S(i).val; // { dg-message "reference to temporary" }
}
constexpr int ary[to_ref(98)] = { }; // { dg-error "25:size of array .ary. is not an integral" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn6.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn6.C
index 17ca6f2..7fada18 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn6.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn6.C
@@ -8,11 +8,11 @@ char& g(char);
double&& g(double);
template <class T> auto&& f(T t)
-{ return g(t); } // { dg-warning "reference to temporary" }
+{ return g(t); } // { dg-message "reference to temporary" }
int main()
{
- ST<decltype(f(1)),int&&>();
- ST<decltype(f('\0')),char&>();
- ST<decltype(f(1.0)),double&&>();
+ ST<decltype(f(1)),int&&>(); // { dg-message "required from here" }
+ ST<decltype(f('\0')),char&>(); // { dg-bogus "required from here" }
+ ST<decltype(f(1.0)),double&&>(); // { dg-bogus "required from here" }
}
diff --git a/gcc/testsuite/g++.dg/other/pr94326.C b/gcc/testsuite/g++.dg/other/pr94326.C
index 4069c03..5df72a6 100644
--- a/gcc/testsuite/g++.dg/other/pr94326.C
+++ b/gcc/testsuite/g++.dg/other/pr94326.C
@@ -3,7 +3,7 @@
// { dg-options "-fcompare-debug" }
template <typename = int> struct A {
- const int &foo() { return 0; } // { dg-warning "returning reference to temporary" }
+ const int &foo() { return 0; } // { dg-message "returning reference to temporary" }
template <typename _Kt> void bar(_Kt) { foo(); }
};
struct B {
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C
index c483601..a9f984c 100644
--- a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C
@@ -3,9 +3,9 @@
struct Base2 { int m_foo; };
struct Derived2 : public Base2 {};
-const Base2& f8() { return Derived2(); } // { dg-warning "reference to temporary" }
+const Base2& f8() { return Derived2(); } // { dg-message "reference to temporary" }
struct foo { };
struct bar { foo base; };
-const foo& f9() { return bar().base; } // { dg-warning "reference to temporary" }
+const foo& f9() { return bar().base; } // { dg-message "reference to temporary" }
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C
index 7609627..69f1e68 100644
--- a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C
@@ -5,4 +5,5 @@
int&& f() { int i = 0; return std::move(i); } // { dg-warning "reference to local variable" }
int&& g() { int i = 0; return std::forward<int>(i); } // { dg-warning "reference to local variable" }
-int&& h() { long l = 0; return std::forward<int>(l); } // { dg-warning "reference to temporary" }
+int&& h() { long l = 0; return std::forward<int>(l); } // { dg-warning "reference to temporary" "" { target { ! c++26 } } }
+// { dg-error "reference to temporary" "" { target c++26 } .-1 }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/warning8.C b/gcc/testsuite/g++.old-deja/g++.jason/warning8.C
index b5ff3f3..2383071 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/warning8.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/warning8.C
@@ -13,5 +13,5 @@ struct B {
const B& f ()
{
A a;
- return a; // { dg-warning "" } returning reference to temporary
+ return a; // { dg-message "" } returning reference to temporary
}