* pt.c (tsubst_default_argument): Use push_to/pop_from_top_level.
* name-lookup.c (do_pushtag): Don't look through complete types, but
don't add to them either. Get context from current_binding_level.
From-SVN: r261656
2018-06-15 Jason Merrill <jason@redhat.com>
+ * name-lookup.c (do_pushtag): Don't look through complete types, but
+ don't add to them either. Get context from current_binding_level.
+ * pt.c (tsubst_default_argument): Use push_to/pop_from_top_level.
+
* decl.c (start_enum): Do compare dependent underlying type.
PR c++/82882 - ICE with lambda in template default argument.
|| (b->kind == sk_template_parms
&& (b->explicit_spec_p || scope == ts_global))
|| (b->kind == sk_class
- && (scope != ts_current
- /* We may be defining a new type in the initializer
- of a static member variable. We allow this when
- not pedantic, and it is particularly useful for
- type punning via an anonymous union. */
- || COMPLETE_TYPE_P (b->this_entity))))
+ && scope != ts_current))
b = b->level_chain;
gcc_assert (identifier_p (name));
if (! context)
{
- tree cs = current_scope ();
-
- /* Avoid setting the lambda context to a current_function_decl that
- we aren't actually inside, e.g. one set by push_access_scope
- during tsubst_default_argument. */
- if (cs && TREE_CODE (cs) == FUNCTION_DECL
- && LAMBDA_TYPE_P (type)
- && !at_function_scope_p ())
- cs = DECL_CONTEXT (cs);
+ cp_binding_level *cb = b;
+ while (cb->kind != sk_namespace
+ && cb->kind != sk_class
+ && (cb->kind != sk_function_parms
+ || !cb->this_entity))
+ cb = cb->level_chain;
+ tree cs = cb->this_entity;
+
+ gcc_checking_assert (TREE_CODE (cs) == FUNCTION_DECL
+ ? cs == current_function_decl
+ : TYPE_P (cs) ? cs == current_class_type
+ : cs == current_namespace);
if (scope == ts_current
|| (cs && TREE_CODE (cs) == FUNCTION_DECL))
if (b->kind == sk_class)
{
- if (!TYPE_BEING_DEFINED (current_class_type)
- && !LAMBDA_TYPE_P (type))
- return error_mark_node;
-
- if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+ if (!TYPE_BEING_DEFINED (current_class_type))
+ /* Don't push anywhere if the class is complete; a lambda in an
+ NSDMI is not a member of the class. */
+ ;
+ else if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
/* Put this TYPE_DECL on the TYPE_FIELDS list for the
class. But if it's a member template class, we want
the TEMPLATE_DECL, not the TYPE_DECL, so this is done
tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
tsubst_flags_t complain)
{
- tree saved_class_ptr = NULL_TREE;
- tree saved_class_ref = NULL_TREE;
int errs = errorcount + sorrycount;
/* This can happen in invalid code. */
we must be careful to do name lookup in the scope of S<T>,
rather than in the current class. */
+ push_to_top_level ();
push_access_scope (fn);
- /* The "this" pointer is not valid in a default argument. */
- if (cfun)
- {
- saved_class_ptr = current_class_ptr;
- cp_function_chain->x_current_class_ptr = NULL_TREE;
- saved_class_ref = current_class_ref;
- cp_function_chain->x_current_class_ref = NULL_TREE;
- }
-
start_lambda_scope (parm);
- push_deferring_access_checks(dk_no_deferred);
/* The default argument expression may cause implicitly defined
member functions to be synthesized, which will result in garbage
collection. We must treat this situation as if we were within
complain, NULL_TREE,
/*integral_constant_expression_p=*/false);
--function_depth;
- pop_deferring_access_checks();
finish_lambda_scope ();
- /* Restore the "this" pointer. */
- if (cfun)
- {
- cp_function_chain->x_current_class_ptr = saved_class_ptr;
- cp_function_chain->x_current_class_ref = saved_class_ref;
- }
-
if (errorcount+sorrycount > errs
&& (complain & tf_warning_or_error))
inform (input_location,
arg = check_default_argument (type, arg, complain);
pop_access_scope (fn);
+ pop_from_top_level ();
if (arg != error_mark_node && !cp_unevaluated_operand)
{
// PR c++/50861
-template<class T> struct A {A(int b=k(0));}; // { dg-error "parameter|argument" }
-void f(int k){A<int> a;} // // { dg-message "declared" }
-// { dg-message "note" "note" { target *-*-* } 3 }
+template<class T> struct A {A(int b=k(0));}; // { dg-error "not declared" }
+ // { dg-error "that depend on a template parameter" "" { target *-*-* } .-1 }
+void f(int k){A<int> a;}