mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 00:51:00 +08:00
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:
parent
76dd48f895
commit
d19aa6af66
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
20
gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C
Normal file
20
gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C
Normal 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 {}; }
|
Loading…
x
Reference in New Issue
Block a user