/* in name-lookup.cc */
extern tree strip_using_decl (tree);
extern void diagnose_name_conflict (tree, tree);
+extern bool dependent_local_decl_p (tree);
/* Tell the binding oracle what kind of binding we are looking for. */
}
}
+/* True if D is a local declaration in dependent scope. Assumes that it is
+ (part of) the current lookup result for its name. */
+
+bool
+dependent_local_decl_p (tree d)
+{
+ if (!DECL_LOCAL_DECL_P (d))
+ return false;
+
+ cxx_binding *b = IDENTIFIER_BINDING (DECL_NAME (d));
+ cp_binding_level *l = b->scope;
+ while (!l->this_entity)
+ l = l->level_chain;
+ return uses_template_parms (l->this_entity);
+}
+
+
+
#include "gt-cp-name-lookup.h"
/* Except that we do substitute default arguments under tsubst_lambda_expr,
since the new op() won't have any associated template arguments for us
to refer to later. */
- if (lambda_fn_in_template_p (in_decl))
+ if (lambda_fn_in_template_p (in_decl)
+ || (in_decl && TREE_CODE (in_decl) == FUNCTION_DECL
+ && DECL_LOCAL_DECL_P (in_decl)))
default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
false/*fn*/, false/*constexpr*/);
if (processing_template_decl)
{
- /* If FN is a local extern declaration or set thereof, look them up
- again at instantiation time. */
+ /* If FN is a local extern declaration (or set thereof) in a template,
+ look it up again at instantiation time. */
if (is_overloaded_fn (fn))
{
tree ifn = get_first_fn (fn);
if (TREE_CODE (ifn) == FUNCTION_DECL
- && DECL_LOCAL_DECL_P (ifn))
+ && dependent_local_decl_p (ifn))
orig_fn = DECL_NAME (ifn);
}
--- /dev/null
+// PR c++/97219
+// { dg-do compile { target c++14 } }
+
+struct B;
+
+template <typename T>
+auto f(T *) {
+ void q(B *, void * = static_cast<T *>(0));
+ return [](auto *p) { q(p); };
+}
+
+void q(void *) = delete;
+
+int main(void) {
+ B *bp = 0;
+ f(bp)(bp);
+}