aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-04-19 16:58:23 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-04-19 16:58:23 +0000
commitfa6098f8177ea7e73cfdcc291209cd47d40196ee (patch)
tree8697179a09947548fbbcca23b0493738bd1f5cb1 /gcc/cp/decl.c
parent74c96e0c149acb69337d704bfcd32d1e60724307 (diff)
downloadgcc-fa6098f8177ea7e73cfdcc291209cd47d40196ee.zip
gcc-fa6098f8177ea7e73cfdcc291209cd47d40196ee.tar.gz
gcc-fa6098f8177ea7e73cfdcc291209cd47d40196ee.tar.bz2
re PR c++/27102 (ICE with invalid class name in function template)
PR c++/27102 * class.c (currently_open_class): Tidy. * decl.c (grokdeclarator): If we encounter an erroneous declarator, assume that we have already issued an error message and return. Return error_mark_node instead of NULL_TREE in more places. Issue errors about function definitions that do not have a function declarator. Check for complete types for all function definitions. * cp-tree.h (cp_error_declarator): Remove. (currently_open_class): Change return type. * parser.c (cp_parser_id_expression): Add optional_p parameter. (cp_parser_parse_diagnose_invalid_type_name): Adjust calls. (cp_parser_id_expression): Likewise. (cp_parser_unqualified_id): If the name is optional, return NULL_TREE. (cp_parser_postfix_dot_deref_expression): Adjust calls. (cp_parser_type_parameter): Likewise. (cp_parser_unqualified_id): Likewise. (cp_parser_direct_declarator): Likewise. (cp_parser_declarator_id): Add optional_p parameter. (cp_parser_function_definition_from_specifiers_and_declarator): Assume that start_function indicates failure only if it has issued an error. (cp_parser_omp_var_list_no_open): Adjust calls. PR c++/27102 * g++.dg/template/crash35.C: Tweak error markers. * g++.dg/template/crash46.C: New test. * g++.old-deja/g++.brendan/friend4.C: Tweak error markers. * g++.old-deja/g++.pt/incomplete1.C: Likewise. From-SVN: r113081
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3d8c2f8..9e101c1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6956,7 +6956,7 @@ grokdeclarator (const cp_declarator *declarator,
break;
case cdk_error:
- break;
+ return error_mark_node;
default:
gcc_unreachable ();
@@ -6966,11 +6966,15 @@ grokdeclarator (const cp_declarator *declarator,
break;
}
- /* A function definition's declarator must have the form of
- a function declarator. */
-
+ /* [dcl.fct.edf]
+
+ The declarator in a function-definition shall have the form
+ D1 ( parameter-declaration-clause) ... */
if (funcdef_flag && innermost_code != cdk_function)
- return NULL_TREE;
+ {
+ error ("function definition does not declare parameters");
+ return error_mark_node;
+ }
if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
&& innermost_code != cdk_function
@@ -7711,6 +7715,20 @@ grokdeclarator (const cp_declarator *declarator,
pedwarn ("extra qualification %<%T::%> on member %qs",
ctype, name);
}
+ else if (/* If the qualifying type is already complete, then we
+ can skip the following checks. */
+ !COMPLETE_TYPE_P (ctype)
+ /* If a function is being defined, then the qualifing
+ type must be complete. The qualifing type may be
+ incomplete for a declaration only if the qualitying
+ type is one of the classes presently being defined,
+ or if it is a dependent type. */
+ && (funcdef_flag
+ || !(dependent_type_p (ctype)
+ || currently_open_class (ctype)))
+ /* Check that the qualifing type is complete. */
+ && !complete_type_or_else (ctype, NULL_TREE))
+ return error_mark_node;
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
tree sname = declarator->u.id.unqualified_name;
@@ -7736,23 +7754,10 @@ grokdeclarator (const cp_declarator *declarator,
TYPE_ARG_TYPES (type));
}
else if (declspecs->specs[(int)ds_typedef]
- || COMPLETE_TYPE_P (complete_type (ctype)))
- {
- /* Have to move this code elsewhere in this function.
- this code is used for i.e., typedef int A::M; M *pm;
-
- It is? How? jason 10/2/94 */
-
- if (current_class_type)
- {
- error ("cannot declare member %<%T::%s%> within %qT",
- ctype, name, current_class_type);
- return void_type_node;
- }
- }
- else
+ && current_class_type)
{
- cxx_incomplete_type_error (NULL_TREE, ctype);
+ error ("cannot declare member %<%T::%s%> within %qT",
+ ctype, name, current_class_type);
return error_mark_node;
}
}