From fc6a28d7633ddd7c734b759f4d60233b70bf1770 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 29 Nov 2004 20:10:18 +0000 Subject: re PR c++/18368 (C++ error message regression) PR c++/18368 * parser.c (cp_parser_check_for_definition_in_return_type): Take the defined type as a parameter, and inform the user about the possibility of a missing semicolon. (cp_parser_explicit_instantiation): Adjust call to cp_parser_check_for_definition_in_return_type. (cp_parser_init_declarator): Likewise. (cp_parser_member_declaration): Likewise. PR c++/18674 * cp-tree.def (TYPENAME_TYPE): Remove discussion of implicit typename from comments. * cp-tree.h (TYPENAME_IS_ENUM_P): New macro. (TYPENAME_IS_CLASS_P): Likewise. (make_typename_type): Change prototype. * decl.c (struct_typename_info): New type. (typename_compare): Expect the second argument to be a typename_info, not a tree. (build_typename_type): Add tag_type parameter. Do not create a new type until necessary. (make_typename_type): Add tag_type parameter. * error.c (TYPENAME_TYPE): Print tags other than "typename" if appropriate. * friend.c (make_friend_class): Adjust call to make_typename_type. * parser.c (cp_parser_make_typename_type): Likewise. (cp_parser_primary_expression): Adjust call to cp_parser_lookup_name. (cp_parser_unqualified_id): Adjust calls to cp_parser_class_name. (cp_parser_class_or_namespace_name): Likewise. (cp_parser_postfix_expression): Adjust calls to make_typename_type. (cp_parser_mem_initializer_id): Adjust calls to cp_parser_class_name. (cp_parser_type_parameter): Adjust calls to cp_parser_lookup_name. (cp_parser_template_name): Likewise. (cp_parser_template_argument): Likewise. (cp_parser_type_name): Adjust call to cp_parser_class_name. (cp_parser_elaborated_type_specifier): Adjust calls to make_typename_type and cp_parser_lookup_name. (cp_parser_namespace_name): Likewise. (cp_parser_class_name): Replace type_p parameter with tag_type. Adjust calls to make_typename_type and cp_parser_lookup_name. (cp_parser_class_head): Adjust calls to cp_parser_class_name. (cp_parser_base_specifier): Likewise. (cp_parser_lookup_name): Replace is_type parameter with tag_type. Adjust calls to make_typename_type and lookup_qualified_name. (cp_parser_lookup_name_simple): Adjust call to cp_parser_lookup_name. (cp_parser_constructor_declarator_p): Adjust call to cp_parser_class_name. * pt.c (convert_template_argument): Adjust all to make_typename_type. (tsubst_decl): Do not pre-substitute the type of the declaration. (tsubst): Hand off declarations more quickly. Adjust call to make_typename_type. PR c++/18512 * parser.c (cp_parser_postfix_dot_deref_expression): Robustify. PR c++/18674 * g++.old-deja/g++.brendan/crash16.C: Adjust error messages. * g++.old-deja/g++.law/ctors5.C: Likewise. * g++.old-deja/g++.other/crash25.C: Likewise. PR c++/18674 * g++.dg/template/error16.C: New test. PR c++/18512 * g++.dg/template/crash29.C: New test. From-SVN: r91483 --- gcc/cp/pt.c | 76 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 26 deletions(-) (limited to 'gcc/cp/pt.c') diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fca3f3d..34e86c8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -140,7 +140,6 @@ static tree most_specialized (tree, tree, tree); static tree most_specialized_class (tree, tree); static int template_class_depth_real (tree, int); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); -static tree tsubst_decl (tree, tree, tree, tsubst_flags_t); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); static void check_specialization_scope (void); @@ -3833,6 +3832,7 @@ convert_template_argument (tree parm, arg = make_typename_type (TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), + typename_type, complain & tf_error); is_type = 1; } @@ -6140,13 +6140,12 @@ tsubst_default_arguments (tree fn) TREE_PURPOSE (arg)); } -/* Substitute the ARGS into the T, which is a _DECL. TYPE is the - (already computed) substitution of ARGS into TREE_TYPE (T), if - appropriate. Return the result of the substitution. Issue error - and warning messages under control of COMPLAIN. */ +/* Substitute the ARGS into the T, which is a _DECL. Return the + result of the substitution. Issue error and warning messages under + control of COMPLAIN. */ static tree -tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) +tsubst_decl (tree t, tree args, tsubst_flags_t complain) { location_t saved_loc; tree r = NULL_TREE; @@ -6267,6 +6266,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree argvec = NULL_TREE; tree *friends; tree gen_tmpl; + tree type; int member; int args_depth; int parms_depth; @@ -6376,7 +6376,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) member = 0; ctx = DECL_CONTEXT (t); } - type = tsubst (type, args, complain, in_decl); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); if (type == error_mark_node) return error_mark_node; @@ -6485,10 +6485,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) case PARM_DECL: { + tree type; + r = copy_node (t); if (DECL_TEMPLATE_PARM_P (t)) SET_DECL_TEMPLATE_PARM_P (r); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -6513,7 +6516,12 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) case FIELD_DECL: { + tree type; + r = copy_decl (t); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + return error_mark_node; TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -6541,19 +6549,6 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) break; case TYPE_DECL: - if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM - || t == TYPE_MAIN_DECL (TREE_TYPE (t))) - { - /* If this is the canonical decl, we don't have to mess with - instantiations, and often we can't (for typename, template - type parms and such). Note that TYPE_NAME is not correct for - the above test if we've copied the type for a typedef. */ - r = TYPE_NAME (type); - break; - } - - /* Fall through. */ - case VAR_DECL: { tree argvec = NULL_TREE; @@ -6561,8 +6556,25 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree spec; tree tmpl = NULL_TREE; tree ctx; + tree type = NULL_TREE; int local_p; + if (TREE_CODE (t) == TYPE_DECL) + { + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM + || t == TYPE_MAIN_DECL (TREE_TYPE (t))) + { + /* If this is the canonical decl, we don't have to + mess with instantiations, and often we can't (for + typename, template type parms and such). Note that + TYPE_NAME is not correct for the above test if + we've copied the type for a typedef. */ + r = TYPE_NAME (type); + break; + } + } + /* Assume this is a non-local variable. */ local_p = 0; @@ -6600,6 +6612,9 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) { + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + return error_mark_node; type = complete_type (type); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t); @@ -6885,6 +6900,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) || TREE_CODE (t) == NAMESPACE_DECL) return t; + if (DECL_P (t)) + return tsubst_decl (t, args, complain); + if (TREE_CODE (t) == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else @@ -6892,9 +6910,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_assert (type != unknown_type_node); - if (type && TREE_CODE (t) != FUNCTION_DECL + if (type && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_DECL && TREE_CODE (t) != IDENTIFIER_NODE && TREE_CODE (t) != FUNCTION_TYPE && TREE_CODE (t) != METHOD_TYPE) @@ -6902,9 +6919,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (type == error_mark_node) return error_mark_node; - if (DECL_P (t)) - return tsubst_decl (t, args, type, complain); - switch (TREE_CODE (t)) { case RECORD_TYPE: @@ -7364,7 +7378,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } - f = make_typename_type (ctx, f, + f = make_typename_type (ctx, f, typename_type, (complain & tf_error) | tf_keep_type_decl); if (f == error_mark_node) return f; @@ -7374,6 +7388,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) f = TREE_TYPE (f); } + if (TREE_CODE (f) != TYPENAME_TYPE) + { + if (TYPENAME_IS_ENUM_P (t) && TREE_CODE (f) != ENUMERAL_TYPE) + error ("%qT resolves to %qT, which is not an enumeration type", + t, f); + else if (TYPENAME_IS_CLASS_P (t) && !CLASS_TYPE_P (f)) + error ("%qT resolves to %qT, which is is not a class type", + t, f); + } + return cp_build_qualified_type_real (f, cp_type_quals (f) | cp_type_quals (t), complain); } -- cgit v1.1