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.
This commit is contained in:
parent
a6e0d59370
commit
5440c88e61
5 changed files with 18 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue