Commit 417ae187 by Jason Merrill Committed by Jason Merrill

DR 1207 PR c++/49003

	DR 1207
	PR c++/49003
	* cp-tree.h (struct saved_scope): Add x_current_class_ptr,
	x_current_class_ref.
	(current_class_ptr, current_class_ref): Use them.
	* decl.c (build_this_parm): Handle getting the class type.
	* parser.c (cp_parser_late_return_type_opt): Set up 'this'
	for use within the trailing return type.

From-SVN: r175671
parent 3fe98897
2011-06-29 Jason Merrill <jason@redhat.com>
DR 1207
PR c++/49003
* cp-tree.h (struct saved_scope): Add x_current_class_ptr,
x_current_class_ref.
(current_class_ptr, current_class_ref): Use them.
* decl.c (build_this_parm): Handle getting the class type.
* parser.c (cp_parser_late_return_type_opt): Set up 'this'
for use within the trailing return type.
* pt.c (tsubst_decl) [VAR_DECL]: In unevaluated operand,
don't tsubst DECL_INITIAL unless our type use auto.
......
......@@ -953,6 +953,10 @@ struct GTY(()) saved_scope {
struct cp_binding_level *x_previous_class_level;
tree x_saved_tree;
/* Only used for uses of this in trailing return type. */
tree x_current_class_ptr;
tree x_current_class_ref;
int x_processing_template_decl;
int x_processing_specialization;
BOOL_BITFIELD x_processing_explicit_instantiation : 1;
......@@ -1070,12 +1074,14 @@ struct GTY(()) language_function {
PARM_DECL for the `this' pointer. The current_class_ref is an
expression for `*this'. */
#define current_class_ptr \
(cfun && cp_function_chain \
? cp_function_chain->x_current_class_ptr : NULL_TREE)
#define current_class_ref \
((cfun && cp_function_chain) \
? cp_function_chain->x_current_class_ref : NULL_TREE)
#define current_class_ptr \
(*(cfun && cp_function_chain \
? &cp_function_chain->x_current_class_ptr \
: &scope_chain->x_current_class_ptr))
#define current_class_ref \
(*(cfun && cp_function_chain \
? &cp_function_chain->x_current_class_ref \
: &scope_chain->x_current_class_ref))
/* The EH_SPEC_BLOCK for the exception-specifiers for the current
function, if any. */
......
......@@ -7001,7 +7001,14 @@ build_this_parm (tree type, cp_cv_quals quals)
tree parm;
cp_cv_quals this_quals;
this_type = type_of_this_parm (type);
if (CLASS_TYPE_P (type))
{
this_type
= cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
this_type = build_pointer_type (this_type);
}
else
this_type = type_of_this_parm (type);
/* The `this' parameter is implicitly `const'; it cannot be
assigned to. */
this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
......@@ -12675,6 +12682,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
cp_function_chain->x_current_class_ref
= cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
/* Set this second to avoid shortcut in cp_build_indirect_ref. */
cp_function_chain->x_current_class_ptr = t;
/* Constructors and destructors need to know whether they're "in
......
......@@ -1696,7 +1696,7 @@ static cp_cv_quals cp_parser_cv_qualifier_seq_opt
static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
(cp_parser *);
static tree cp_parser_late_return_type_opt
(cp_parser *);
(cp_parser *, cp_cv_quals);
static tree cp_parser_declarator_id
(cp_parser *, bool);
static tree cp_parser_type_id
......@@ -14968,7 +14968,7 @@ cp_parser_direct_declarator (cp_parser* parser,
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
late_return
= cp_parser_late_return_type_opt (parser);
= cp_parser_late_return_type_opt (parser, cv_quals);
/* Create the function-declarator. */
declarator = make_call_declarator (declarator,
......@@ -15537,9 +15537,10 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser)
Returns the type indicated by the type-id. */
static tree
cp_parser_late_return_type_opt (cp_parser* parser)
cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
{
cp_token *token;
tree type;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
......@@ -15550,7 +15551,23 @@ cp_parser_late_return_type_opt (cp_parser* parser)
/* Consume the ->. */
cp_lexer_consume_token (parser->lexer);
return cp_parser_trailing_type_id (parser);
if (current_class_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);
current_class_ref
= 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);
if (current_class_type)
current_class_ptr = current_class_ref = NULL_TREE;
return type;
}
/* Parse a declarator-id.
......
2011-06-29 Jason Merrill <jason@redhat.com>
PR c++/49003
* g++.dg/cpp0x/trailing6.C: New.
* g++.dg/cpp0x/pr45908.C: No error.
PR c++/49272
* g++.old-deja/g++.jason/rfg10.C: Accept other overflow error too.
......
......@@ -14,5 +14,5 @@ struct vector {
class block {
vector v;
auto end() const -> decltype(v.begin())
{ return v.begin(); } // { dg-error "could not convert" }
{ return v.begin(); }
};
// PR c++/49003
// { dg-options -std=c++0x }
struct A {
auto a() const -> decltype(this) { return this; }
};
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