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.
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;
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. */
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;
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
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
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,
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);
/* 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.
class block {
vector v;
auto end() const -> decltype(v.begin())
- { return v.begin(); } // { dg-error "could not convert" }
+ { return v.begin(); }
};
--- /dev/null
+// PR c++/49003
+// { dg-options -std=c++0x }
+
+struct A {
+ auto a() const -> decltype(this) { return this; }
+};