From: Jason Merrill Date: Fri, 15 Jun 2018 20:23:00 +0000 (-0400) Subject: pt.c (tsubst_default_argument): Use push_to/pop_from_top_level. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fe7a23a611df9954918f334f855935ce228c88d6;p=gcc.git pt.c (tsubst_default_argument): Use push_to/pop_from_top_level. * 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d8ce66eb22c..56fe205fdbc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-06-15 Jason Merrill + * 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. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 7990029d70c..ec001016d3e 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -6521,12 +6521,7 @@ do_pushtag (tree name, tree type, tag_scope scope) || (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)); @@ -6540,15 +6535,18 @@ do_pushtag (tree name, tree type, tag_scope scope) 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)) @@ -6587,11 +6585,11 @@ do_pushtag (tree name, tree type, tag_scope scope) 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 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ed634ddeefb..4ee84b201e9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12675,8 +12675,6 @@ tree 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. */ @@ -12709,19 +12707,10 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg, we must be careful to do name lookup in the scope of S, 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 @@ -12732,17 +12721,9 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg, 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, @@ -12752,6 +12733,7 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg, arg = check_default_argument (type, arg, complain); pop_access_scope (fn); + pop_from_top_level (); if (arg != error_mark_node && !cp_unevaluated_operand) { diff --git a/gcc/testsuite/g++.dg/template/crash108.C b/gcc/testsuite/g++.dg/template/crash108.C index 9bcabc6009b..3ffadc14c25 100644 --- a/gcc/testsuite/g++.dg/template/crash108.C +++ b/gcc/testsuite/g++.dg/template/crash108.C @@ -1,5 +1,5 @@ // PR c++/50861 -template struct A {A(int b=k(0));}; // { dg-error "parameter|argument" } -void f(int k){A a;} // // { dg-message "declared" } -// { dg-message "note" "note" { target *-*-* } 3 } +template 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 a;}