Commit 382346e5 by Jason Merrill Committed by Jason Merrill

parser.c (inject_this_parameter): Split out from cp_parser_late_return_type_opt.

	* parser.c (inject_this_parameter): Split out from
	cp_parser_late_return_type_opt.
	(cp_parser_class_specifier_1): Use it for NSDMIs.
	* tree.c (bot_replace): Replace NSDMI 'this' with real 'this'.

From-SVN: r179179
parent 02aaf894
2011-09-25 Jason Merrill <jason@redhat.com>
* parser.c (inject_this_parameter): Split out from
cp_parser_late_return_type_opt.
(cp_parser_class_specifier_1): Use it for NSDMIs.
* tree.c (bot_replace): Replace NSDMI 'this' with real 'this'.
2011-09-24 Jason Merrill <jason@redhat.com> 2011-09-24 Jason Merrill <jason@redhat.com>
* except.c (expr_noexcept_p): Split out from finish_noexcept_expr. * except.c (expr_noexcept_p): Split out from finish_noexcept_expr.
......
...@@ -15690,6 +15690,31 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser) ...@@ -15690,6 +15690,31 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser)
return virt_specifiers; return virt_specifiers;
} }
/* Used by handling of trailing-return-types and NSDMI, in which 'this'
is in scope even though it isn't real. */
static void
inject_this_parameter (tree ctype, cp_cv_quals quals)
{
tree this_parm;
if (current_class_ptr)
{
/* We don't clear this between NSDMIs. Is it already what we want? */
tree type = TREE_TYPE (TREE_TYPE (current_class_ptr));
if (same_type_ignoring_top_level_qualifiers_p (ctype, type)
&& cp_type_quals (type) == quals)
return;
}
this_parm = build_this_parm (ctype, quals);
/* Clear this first to avoid shortcut in cp_build_indirect_ref. */
current_class_ptr = NULL_TREE;
current_class_ref
= cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
current_class_ptr = this_parm;
}
/* Parse a late-specified return type, if any. This is not a separate /* Parse a late-specified return type, if any. This is not a separate
non-terminal, but part of a function declarator, which looks like non-terminal, but part of a function declarator, which looks like
...@@ -15718,12 +15743,8 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals) ...@@ -15718,12 +15743,8 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
if (quals >= 0) if (quals >= 0)
{ {
/* DR 1207: 'this' is in scope in the trailing return type. */ /* DR 1207: 'this' is in scope in the trailing return type. */
tree this_parm = build_this_parm (current_class_type, quals);
gcc_assert (current_class_ptr == NULL_TREE); gcc_assert (current_class_ptr == NULL_TREE);
current_class_ref inject_this_parameter (current_class_type, quals);
= cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
/* Set this second to avoid shortcut in cp_build_indirect_ref. */
current_class_ptr = this_parm;
} }
type = cp_parser_trailing_type_id (parser); type = cp_parser_trailing_type_id (parser);
...@@ -17274,6 +17295,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -17274,6 +17295,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
tree pushed_scope = NULL_TREE; tree pushed_scope = NULL_TREE;
unsigned ix; unsigned ix;
cp_default_arg_entry *e; cp_default_arg_entry *e;
tree save_ccp, save_ccr;
/* In a first pass, parse default arguments to the functions. /* In a first pass, parse default arguments to the functions.
Then, in a second pass, parse the bodies of the functions. Then, in a second pass, parse the bodies of the functions.
...@@ -17307,6 +17329,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -17307,6 +17329,8 @@ cp_parser_class_specifier_1 (cp_parser* parser)
} }
VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0); VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0);
/* Now parse any NSDMIs. */ /* Now parse any NSDMIs. */
save_ccp = current_class_ptr;
save_ccr = current_class_ref;
FOR_EACH_VEC_ELT (tree, unparsed_nsdmis, ix, decl) FOR_EACH_VEC_ELT (tree, unparsed_nsdmis, ix, decl)
{ {
if (class_type != DECL_CONTEXT (decl)) if (class_type != DECL_CONTEXT (decl))
...@@ -17316,9 +17340,12 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -17316,9 +17340,12 @@ cp_parser_class_specifier_1 (cp_parser* parser)
class_type = DECL_CONTEXT (decl); class_type = DECL_CONTEXT (decl);
pushed_scope = push_scope (class_type); pushed_scope = push_scope (class_type);
} }
inject_this_parameter (class_type, TYPE_UNQUALIFIED);
cp_parser_late_parsing_nsdmi (parser, decl); cp_parser_late_parsing_nsdmi (parser, decl);
} }
VEC_truncate (tree, unparsed_nsdmis, 0); VEC_truncate (tree, unparsed_nsdmis, 0);
current_class_ptr = save_ccp;
current_class_ref = save_ccr;
if (pushed_scope) if (pushed_scope)
pop_scope (pushed_scope); pop_scope (pushed_scope);
/* Now parse the body of the functions. */ /* Now parse the body of the functions. */
......
...@@ -1926,6 +1926,13 @@ bot_replace (tree* t, ...@@ -1926,6 +1926,13 @@ bot_replace (tree* t,
if (n) if (n)
*t = (tree) n->value; *t = (tree) n->value;
} }
else if (TREE_CODE (*t) == PARM_DECL
&& DECL_NAME (*t) == this_identifier)
{
/* In an NSDMI we need to replace the 'this' parameter we used for
parsing with the real one for this function. */
*t = current_class_ptr;
}
return NULL_TREE; return NULL_TREE;
} }
......
2011-09-25 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/nsdmi-defer4.C: New.
2011-09-25 Eric Botcazou <ebotcazou@adacore.com> 2011-09-25 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/frame_overflow.ads: New. * gnat.dg/frame_overflow.ads: New.
......
// { dg-options -std=c++0x }
struct A
{
int i = 42;
int j = f();
int k = this->f();
int f() { return i++; }
};
A a;
int main()
{
if (a.j != 42 || a.k != 43 || a.i != 44)
__builtin_abort();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment