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> 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, * pt.c (tsubst_decl) [VAR_DECL]: In unevaluated operand,
don't tsubst DECL_INITIAL unless our type use auto. don't tsubst DECL_INITIAL unless our type use auto.
......
...@@ -953,6 +953,10 @@ struct GTY(()) saved_scope { ...@@ -953,6 +953,10 @@ struct GTY(()) saved_scope {
struct cp_binding_level *x_previous_class_level; struct cp_binding_level *x_previous_class_level;
tree x_saved_tree; 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_template_decl;
int x_processing_specialization; int x_processing_specialization;
BOOL_BITFIELD x_processing_explicit_instantiation : 1; BOOL_BITFIELD x_processing_explicit_instantiation : 1;
...@@ -1070,12 +1074,14 @@ struct GTY(()) language_function { ...@@ -1070,12 +1074,14 @@ struct GTY(()) language_function {
PARM_DECL for the `this' pointer. The current_class_ref is an PARM_DECL for the `this' pointer. The current_class_ref is an
expression for `*this'. */ expression for `*this'. */
#define current_class_ptr \ #define current_class_ptr \
(cfun && cp_function_chain \ (*(cfun && cp_function_chain \
? cp_function_chain->x_current_class_ptr : NULL_TREE) ? &cp_function_chain->x_current_class_ptr \
#define current_class_ref \ : &scope_chain->x_current_class_ptr))
((cfun && cp_function_chain) \ #define current_class_ref \
? cp_function_chain->x_current_class_ref : NULL_TREE) (*(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 /* The EH_SPEC_BLOCK for the exception-specifiers for the current
function, if any. */ function, if any. */
......
...@@ -7001,7 +7001,14 @@ build_this_parm (tree type, cp_cv_quals quals) ...@@ -7001,7 +7001,14 @@ build_this_parm (tree type, cp_cv_quals quals)
tree parm; tree parm;
cp_cv_quals this_quals; 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 /* The `this' parameter is implicitly `const'; it cannot be
assigned to. */ assigned to. */
this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST; this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
...@@ -12675,6 +12682,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -12675,6 +12682,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
cp_function_chain->x_current_class_ref cp_function_chain->x_current_class_ref
= cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error); = 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; cp_function_chain->x_current_class_ptr = t;
/* Constructors and destructors need to know whether they're "in /* Constructors and destructors need to know whether they're "in
......
...@@ -1696,7 +1696,7 @@ static cp_cv_quals cp_parser_cv_qualifier_seq_opt ...@@ -1696,7 +1696,7 @@ static cp_cv_quals cp_parser_cv_qualifier_seq_opt
static cp_virt_specifiers cp_parser_virt_specifier_seq_opt static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
(cp_parser *); (cp_parser *);
static tree cp_parser_late_return_type_opt static tree cp_parser_late_return_type_opt
(cp_parser *); (cp_parser *, cp_cv_quals);
static tree cp_parser_declarator_id static tree cp_parser_declarator_id
(cp_parser *, bool); (cp_parser *, bool);
static tree cp_parser_type_id static tree cp_parser_type_id
...@@ -14968,7 +14968,7 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -14968,7 +14968,7 @@ cp_parser_direct_declarator (cp_parser* parser,
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser); virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
late_return late_return
= cp_parser_late_return_type_opt (parser); = cp_parser_late_return_type_opt (parser, cv_quals);
/* Create the function-declarator. */ /* Create the function-declarator. */
declarator = make_call_declarator (declarator, declarator = make_call_declarator (declarator,
...@@ -15537,9 +15537,10 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser) ...@@ -15537,9 +15537,10 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser)
Returns the type indicated by the type-id. */ Returns the type indicated by the type-id. */
static tree 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; cp_token *token;
tree type;
/* Peek at the next token. */ /* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
...@@ -15550,7 +15551,23 @@ cp_parser_late_return_type_opt (cp_parser* parser) ...@@ -15550,7 +15551,23 @@ cp_parser_late_return_type_opt (cp_parser* parser)
/* Consume the ->. */ /* Consume the ->. */
cp_lexer_consume_token (parser->lexer); 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. /* Parse a declarator-id.
......
2011-06-29 Jason Merrill <jason@redhat.com> 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 PR c++/49272
* g++.old-deja/g++.jason/rfg10.C: Accept other overflow error too. * g++.old-deja/g++.jason/rfg10.C: Accept other overflow error too.
......
...@@ -14,5 +14,5 @@ struct vector { ...@@ -14,5 +14,5 @@ struct vector {
class block { class block {
vector v; vector v;
auto end() const -> decltype(v.begin()) 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