PR c++/77337 - auto return and lambda
* pt.c (tsubst_friend_function): Don't set DECL_INITIAL. (instantiate_decl): It's OK to defer a constexpr function. * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): Check DECL_LANG_SPECIFIC. * decl2.c (decl_defined_p): Use it. No longer static. * decl.c (redeclaration_error_message): Use decl_defined_p. * constexpr.c (cxx_eval_call_expression): Set input_location around call to instantiate_decl. From-SVN: r242056
This commit is contained in:
parent
28d1bf4464
commit
f065303fcf
7 changed files with 54 additions and 12 deletions
|
@ -1,3 +1,15 @@
|
|||
2016-11-10 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/77337
|
||||
* pt.c (tsubst_friend_function): Don't set DECL_INITIAL.
|
||||
(instantiate_decl): It's OK to defer a constexpr function.
|
||||
* cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): Check
|
||||
DECL_LANG_SPECIFIC.
|
||||
* decl2.c (decl_defined_p): Use it. No longer static.
|
||||
* decl.c (redeclaration_error_message): Use decl_defined_p.
|
||||
* constexpr.c (cxx_eval_call_expression): Set input_location around
|
||||
call to instantiate_decl.
|
||||
|
||||
2016-11-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* mangle.c (mangle_decl): Only emit -Wc++1z-compat warnings for
|
||||
|
|
|
@ -1464,9 +1464,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
|
|||
if (!DECL_INITIAL (fun)
|
||||
&& DECL_TEMPLOID_INSTANTIATION (fun))
|
||||
{
|
||||
location_t save_loc = input_location;
|
||||
input_location = loc;
|
||||
++function_depth;
|
||||
instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
|
||||
--function_depth;
|
||||
input_location = save_loc;
|
||||
}
|
||||
|
||||
/* If in direct recursive call, optimize definition search. */
|
||||
|
|
|
@ -4380,7 +4380,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be
|
||||
a DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. */
|
||||
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
|
||||
(DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
|
||||
(DECL_LANG_SPECIFIC (DECL) && DECL_TEMPLATE_INFO (DECL) \
|
||||
&& !DECL_USE_TEMPLATE (DECL))
|
||||
|
||||
/* Nonzero if DECL is a function generated from a function 'temploid',
|
||||
i.e. template, member of class template, or dependent friend. */
|
||||
|
@ -5895,6 +5896,7 @@ extern void import_export_decl (tree);
|
|||
extern tree build_cleanup (tree);
|
||||
extern tree build_offset_ref_call_from_tree (tree, vec<tree, va_gc> **,
|
||||
tsubst_flags_t);
|
||||
extern bool decl_defined_p (tree);
|
||||
extern bool decl_constant_var_p (tree);
|
||||
extern bool decl_maybe_constant_var_p (tree);
|
||||
extern void no_linkage_error (tree);
|
||||
|
|
|
@ -2778,8 +2778,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
|
|||
warn_extern_redeclared_static. */
|
||||
|
||||
/* Defining the same name twice is no good. */
|
||||
if (DECL_INITIAL (olddecl) != NULL_TREE
|
||||
&& DECL_INITIAL (newdecl) != NULL_TREE)
|
||||
if (decl_defined_p (olddecl)
|
||||
&& decl_defined_p (newdecl))
|
||||
{
|
||||
if (DECL_NAME (olddecl) == NULL_TREE)
|
||||
return G_("%q#D not declared in class");
|
||||
|
|
|
@ -80,7 +80,6 @@ static void import_export_class (tree);
|
|||
static tree get_guard_bits (tree);
|
||||
static void determine_visibility_from_class (tree, tree);
|
||||
static bool determine_hidden_inline (tree);
|
||||
static bool decl_defined_p (tree);
|
||||
static void maybe_instantiate_decl (tree);
|
||||
|
||||
/* A list of static class variables. This is needed, because a
|
||||
|
@ -4085,11 +4084,15 @@ collect_ada_namespace (tree namespc, const char *source_file)
|
|||
/* Returns true iff there is a definition available for variable or
|
||||
function DECL. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
decl_defined_p (tree decl)
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
return (DECL_INITIAL (decl) != NULL_TREE);
|
||||
return (DECL_INITIAL (decl) != NULL_TREE
|
||||
/* A pending instantiation of a friend temploid is defined. */
|
||||
|| (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
|
||||
&& DECL_INITIAL (DECL_TEMPLATE_RESULT
|
||||
(DECL_TI_TEMPLATE (decl)))));
|
||||
else
|
||||
{
|
||||
gcc_assert (VAR_P (decl));
|
||||
|
|
|
@ -9383,10 +9383,6 @@ tsubst_friend_function (tree decl, tree args)
|
|||
else
|
||||
new_friend_result_template_info = NULL_TREE;
|
||||
|
||||
/* Make the init_value nonzero so pushdecl knows this is a defn. */
|
||||
if (new_friend_is_defn)
|
||||
DECL_INITIAL (new_friend) = error_mark_node;
|
||||
|
||||
/* Inside pushdecl_namespace_level, we will push into the
|
||||
current namespace. However, the friend function should go
|
||||
into the namespace of the template. */
|
||||
|
@ -22086,8 +22082,7 @@ instantiate_decl (tree d, int defer_ok,
|
|||
case that an expression refers to the value of the variable --
|
||||
if the variable has a constant value the referring expression can
|
||||
take advantage of that fact. */
|
||||
if (VAR_P (d)
|
||||
|| DECL_DECLARED_CONSTEXPR_P (d))
|
||||
if (VAR_P (d))
|
||||
defer_ok = 0;
|
||||
|
||||
/* Don't instantiate cloned functions. Instead, instantiate the
|
||||
|
|
27
gcc/testsuite/g++.dg/cpp1y/auto-fn33.C
Normal file
27
gcc/testsuite/g++.dg/cpp1y/auto-fn33.C
Normal file
|
@ -0,0 +1,27 @@
|
|||
// PR c++/77337
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
template<typename Functor>
|
||||
struct fix_type {
|
||||
Functor functor;
|
||||
|
||||
decltype(auto) operator()()
|
||||
{ return functor(*this); }
|
||||
};
|
||||
|
||||
template<typename Functor>
|
||||
fix_type<Functor> fix(Functor functor)
|
||||
{ return { functor }; }
|
||||
|
||||
int main()
|
||||
{
|
||||
auto zero = fix
|
||||
([](auto& self) -> int // N.B. non-deduced, non-dependent return type
|
||||
{
|
||||
return 0;
|
||||
|
||||
self(); // error: use of 'decltype(auto) fix_type<Functor>::operator()() [with Functor = main()::<lambda(auto:1&)>]' before deduction of 'auto'
|
||||
});
|
||||
|
||||
return zero();
|
||||
}
|
Loading…
Add table
Reference in a new issue