c++: Set the locus of the function result decl

gcc/cp/ChangeLog:

	* decl.cc (grokdeclarator): Build RESULT_DECL.
	(start_preparsed_function): Copy location from template.
	* semantics.cc (apply_deduced_return_type): Handle
	arg != current_function_decl.
	* method.cc (implicitly_declare_fn): Use it.

gcc/ChangeLog:

	* function.cc (init_function_start): Use DECL_RESULT location
	for -Waggregate-return warning.

gcc/testsuite/ChangeLog:

	* g++.dg/diagnostic/return-type-loc1.C: New test.

Co-authored-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
Bernhard Reutner-Fischer 2022-11-20 18:06:04 +01:00 committed by Jason Merrill
parent 76dd48f895
commit d19aa6af66
5 changed files with 53 additions and 12 deletions

View File

@ -14772,6 +14772,19 @@ grokdeclarator (const cp_declarator *declarator,
else if (constinit_p)
DECL_DECLARED_CONSTINIT_P (decl) = true;
}
else if (TREE_CODE (decl) == FUNCTION_DECL)
{
/* If we saw a return type, record its location. */
location_t loc = declspecs->locations[ds_type_spec];
if (loc != UNKNOWN_LOCATION)
{
tree restype = TREE_TYPE (TREE_TYPE (decl));
tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (decl) = resdecl;
}
}
/* Record constancy and volatility on the DECL itself . There's
no need to do this when processing a template; we'll do this
@ -17326,9 +17339,17 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
if (DECL_RESULT (decl1) == NULL_TREE)
{
tree resdecl;
/* In a template instantiation, copy the return type location. When
parsing, the location will be set in grokdeclarator. */
location_t loc = input_location;
if (DECL_TEMPLATE_INSTANTIATION (decl1))
{
tree tmpl = template_for_substitution (decl1);
if (tree res = DECL_RESULT (DECL_TEMPLATE_RESULT (tmpl)))
loc = DECL_SOURCE_LOCATION (res);
}
resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (decl1) = resdecl;

View File

@ -3079,7 +3079,7 @@ implicitly_declare_fn (special_function_kind kind, tree type,
{
fn = copy_operator_fn (pattern_fn, EQ_EXPR);
DECL_ARTIFICIAL (fn) = 1;
TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
apply_deduced_return_type (fn, boolean_type_node);
return fn;
}

View File

@ -12325,24 +12325,23 @@ apply_deduced_return_type (tree fco, tree return_type)
/* We already have a DECL_RESULT from start_preparsed_function.
Now we need to redo the work it and allocate_struct_function
did to reflect the new type. */
gcc_assert (current_function_decl == fco);
result = build_decl (input_location, RESULT_DECL, NULL_TREE,
result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
TYPE_MAIN_VARIANT (return_type));
DECL_ARTIFICIAL (result) = 1;
DECL_IGNORED_P (result) = 1;
cp_apply_type_quals_to_decl (cp_type_quals (return_type),
result);
DECL_RESULT (fco) = result;
if (!processing_template_decl)
{
bool aggr = aggregate_value_p (result, fco);
if (function *fun = DECL_STRUCT_FUNCTION (fco))
{
bool aggr = aggregate_value_p (result, fco);
#ifdef PCC_STATIC_STRUCT_RETURN
cfun->returns_pcc_struct = aggr;
fun->returns_pcc_struct = aggr;
#endif
cfun->returns_struct = aggr;
}
fun->returns_struct = aggr;
}
}
/* DECL is a local variable or parameter from the surrounding scope of a

View File

@ -4997,7 +4997,8 @@ init_function_start (tree subr)
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */
if (AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
warning (OPT_Waggregate_return, "function returns an aggregate");
warning_at (DECL_SOURCE_LOCATION (DECL_RESULT (subr)),
OPT_Waggregate_return, "function returns an aggregate");
}
/* Expand code to verify the stack_protect_guard. This is invoked at

View File

@ -0,0 +1,20 @@
// { dg-do compile { target c++11 } }
// { dg-additional-options -Waggregate-return }
struct B { int i,j; };
template <class T>
struct A
{
template <class U>
U // { dg-warning "aggregate" }
f() { return {}; }
};
int main()
{
A<int>().f<B>(); // { dg-warning "aggregate" }
}
B // { dg-warning "aggregate" }
g() { return {}; }