diff options
author | Jason Merrill <jason@redhat.com> | 2008-09-08 20:52:44 +0000 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2008-09-08 20:52:44 +0000 |
commit | e53d89be1afb085a30e1874f35a4fe87b4d7957e (patch) | |
tree | 0142184b1cea337fc342e6818257e4f6cb77fa58 /gcc/cp/pt.c | |
parent | 0a58b407840a14b27dfe9d86decc23e54c8d8570 (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.c | 32 |
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); |