aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-11-19 17:01:10 -0500
committerJason Merrill <jason@redhat.com>2021-11-22 17:42:53 -0500
commit5440c88e61f5c624eb87e19801eef6eedf27e8ab (patch)
treec5ede3ce9a981ca2934d5a24df4b7102c8ef5e42 /gcc
parenta6e0d593707ae44dec0bdf2bcdc4f539050b46db (diff)
downloadgcc-5440c88e61f5c624eb87e19801eef6eedf27e8ab.zip
gcc-5440c88e61f5c624eb87e19801eef6eedf27e8ab.tar.gz
gcc-5440c88e61f5c624eb87e19801eef6eedf27e8ab.tar.bz2
c++: improved return expression location
Stripping the location wrapper from retval meant we didn't have the necessary location information for any conversion diagnostics. We only need the stripping for the named return value optimization, let's use the unstripped expression for everything else. gcc/cp/ChangeLog: * typeck.c (check_return_expr): Only strip location wrapper during NRV handling. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/pr65327.C: Adjust location. * g++.dg/cpp23/constexpr-nonlit4.C: Likewise. * g++.dg/cpp23/constexpr-nonlit5.C: Likewise. * g++.dg/cpp2a/constexpr-init1.C: Likewise.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/typeck.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr65327.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C4
5 files changed, 18 insertions, 17 deletions
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 58919aa..63a0eae 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -10545,19 +10545,20 @@ check_return_expr (tree retval, bool *no_warning)
this restriction, anyway. (jason 2000-11-19)
See finish_function and finalize_nrv for the rest of this optimization. */
+ tree bare_retval = NULL_TREE;
if (retval)
{
retval = maybe_undo_parenthesized_ref (retval);
- STRIP_ANY_LOCATION_WRAPPER (retval);
+ bare_retval = tree_strip_any_location_wrapper (retval);
}
- bool named_return_value_okay_p = can_do_nrvo_p (retval, functype);
+ bool named_return_value_okay_p = can_do_nrvo_p (bare_retval, functype);
if (fn_returns_value_p && flag_elide_constructors)
{
if (named_return_value_okay_p
&& (current_function_return_value == NULL_TREE
- || current_function_return_value == retval))
- current_function_return_value = retval;
+ || current_function_return_value == bare_retval))
+ current_function_return_value = bare_retval;
else
current_function_return_value = error_mark_node;
}
@@ -10571,7 +10572,7 @@ check_return_expr (tree retval, bool *no_warning)
maybe_warn_pessimizing_move (retval, functype);
/* Do any required conversions. */
- if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
+ if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
/* No conversions are required. */
;
else
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr65327.C b/gcc/testsuite/g++.dg/cpp0x/pr65327.C
index 6e888eb..e814995 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr65327.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr65327.C
@@ -14,5 +14,5 @@ foo ()
constexpr volatile int // { dg-warning "deprecated" "" { target c++2a } }
bar ()
{
- return i;
-} // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+ return i; // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
index e4ed2e3..bdc97a9 100644
--- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
@@ -34,7 +34,7 @@ baz (int x)
{
static const int v = qux (); // { dg-message "'v' was not initialized with a constant expression" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
@@ -46,12 +46,12 @@ corge (int x)
{
const thread_local int v = qux (); // { dg-message "'v' was not initialized with a constant expression" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
constexpr int a = foo (12);
constexpr int b = bar (12);
-constexpr int c = baz (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
-constexpr int d = corge (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
+constexpr int c = baz (12);
+constexpr int d = corge (12);
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
index 838f282..86d5dba 100644
--- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
@@ -34,7 +34,7 @@ baz (int x)
{
static int v = 6; // { dg-message "int v' is not const" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
@@ -46,12 +46,12 @@ corge (int x)
{
thread_local int v = 6; // { dg-message "int v' is not const" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
constexpr int a = foo (12);
constexpr int b = bar (12);
-constexpr int c = baz (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
-constexpr int d = corge (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
+constexpr int c = baz (12);
+constexpr int d = corge (12);
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C
index 75984a2..e56ecfe 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C
@@ -73,11 +73,11 @@ fn7 (bool b)
int a; // { dg-message ".int a. is not const" }
if (b)
a = 42;
- return a;
+ return a; // { dg-error "the value of .a. is not usable" }
}
static_assert (fn7 (true) == 42);
-static_assert (fn7 (false) == 42); // { dg-error "non-constant condition|the value of .a. is not usable" }
+static_assert (fn7 (false) == 42); // { dg-error "non-constant condition" }
// { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-1 }
constexpr int