aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-09-08 20:52:44 +0000
committerJason Merrill <jason@redhat.com>2008-09-08 20:52:44 +0000
commite53d89be1afb085a30e1874f35a4fe87b4d7957e (patch)
tree0142184b1cea337fc342e6818257e4f6cb77fa58 /gcc/cp/pt.c
parent0a58b407840a14b27dfe9d86decc23e54c8d8570 (diff)
PR c++/37302
* parser.c (cp_parser_parameter_declaration_list): Process the PARM_DECLs as we go and push them. Return a TREE_LIST. (cp_parser_parameter_declaration_clause): Return a TREE_LIST. (cp_parser_direct_declarator): Create a binding level and suppress deprecated warnings in the parameter list. (make_call_declarator): PARMS is now a tree. * cp-tree.h (struct cp_declarator): Function parms are now a tree. * decl.h (enum deprecated_states, deprecated_state): Move here. * decl.c: From here. (type_is_deprecated): New fn. (grokparms): PARMLIST is a tree now. Warn about parms that use deprecated types. * mangle.c (write_expression): Handle PARM_DECL, CALL_EXPR and 0-operand cast. * pt.c (tsubst) [DECLTYPE_TYPE]: Set skip_evaluation. (tsubst_copy) [PARM_DECL]: Handle a PARM_DECL used outside of a function. * name-lookup.c (pushtag): Look through function parameter scopes. (pushdecl_maybe_friend): Don't set DECL_CONTEXT on a PARM_DECL when we're parsing a function declarator. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@140120 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7c9165c20ea..4aa7b1ad146 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -9556,11 +9556,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree type;
- type =
- finish_decltype_type (tsubst_expr
- (DECLTYPE_TYPE_EXPR (t), args,
- complain, in_decl,
- /*integral_constant_expression_p=*/false),
+ ++skip_evaluation;
+
+ type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args,
+ complain, in_decl,
+ /*integral_constant_expression_p=*/false);
+
+ --skip_evaluation;
+
+ type =
+ finish_decltype_type (type,
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
return cp_build_qualified_type_real (type,
cp_type_quals (t)
@@ -9796,7 +9801,22 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
case PARM_DECL:
r = retrieve_local_specialization (t);
- gcc_assert (r != NULL);
+
+ if (r == NULL)
+ {
+ /* This can happen for a parameter name used later in a function
+ declaration (such as in a late-specified return type).
+ Replace it with an arbitrary expression with the same type
+ (*(T*)0). This should only occur in an unevaluated context
+ (i.e. decltype). */
+ gcc_assert (skip_evaluation && DECL_CONTEXT (t) == NULL_TREE);
+ r = non_reference (TREE_TYPE (t));
+ r = tsubst (r, args, complain, in_decl);
+ r = build_pointer_type (r);
+ r = build_c_cast (r, null_node);
+ return cp_build_indirect_ref (r, NULL, tf_warning_or_error);
+ }
+
if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
r = ARGUMENT_PACK_SELECT_ARG (r);
mark_used (r);