aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-06-15 16:23:00 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-06-15 16:23:00 -0400
commitfe7a23a611df9954918f334f855935ce228c88d6 (patch)
tree687801a448df6ff82ba9113374bdf6b8eece3207
parentb4cf2e42b5d30bd38b05c16365ab8e5c98f7e12a (diff)
downloadgcc-fe7a23a611df9954918f334f855935ce228c88d6.zip
gcc-fe7a23a611df9954918f334f855935ce228c88d6.tar.gz
gcc-fe7a23a611df9954918f334f855935ce228c88d6.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/name-lookup.c38
-rw-r--r--gcc/cp/pt.c22
-rw-r--r--gcc/testsuite/g++.dg/template/crash108.C6
4 files changed, 27 insertions, 43 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d8ce66e..56fe205 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
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.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 7990029..ec00101 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 ed634dd..4ee84b2 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<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
@@ -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 9bcabc6..3ffadc1 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<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;}