C++ PATCH: PR 18124, 18155, 18177
Mark Mitchell
mark@codesourcery.com
Wed Nov 3 02:55:00 GMT 2004
This patch fixes three minor C++ regressions. PR 18124 was a case
where we just didn't check for error_mark_node. PR 18155 was a case
where we didn't check for invalid template typedefs when no
typedef-name was specified. I was able to improve error recovery
there a little bit too, which removed a pointless error on
g++.dg/parse/crash13.C. And PR 18177 was an ice-on-invalid when using
a const_cast on an undeclared variable.
Tested on i686-pc-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2004-11-02 Mark Mitchell <mark@codesourcery.com>
PR c++/18124
* parser.c (cp_parser_type_parameter): Robustify.
PR c++/18155
* parser.c (cp_parser_single_declaration): Disallow template
typedefs.
PR c++/18177
* typeck.c (build_const_cast): Use error_operand_p.
2004-11-02 Mark Mitchell <mark@codesourcery.com>
PR c++/18124
* g++.dg/template/crash25.C: New test.
PR c++/18155
* g++.dg/template/typedef2.C: New test.
* g++.dg/parse/crash13.C: Adjust error markers.
PR c++/18177
* g++.dg/conversion/const3.C: New test.
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.275
diff -c -5 -p -r1.275 parser.c
*** cp/parser.c 1 Nov 2004 09:47:57 -0000 1.275
--- cp/parser.c 3 Nov 2004 02:24:28 -0000
*************** cp_parser_type_parameter (cp_parser* par
*** 8184,8196 ****
the end of the parameter-list. If the next token is a `,',
then we are at the end of this parameter. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
! identifier = cp_parser_identifier (parser);
else
identifier = NULL_TREE;
/* Create the template parameter. */
parameter = finish_template_template_parm (class_type_node,
identifier);
/* If the next token is an `=', then there is a
--- 8184,8202 ----
the end of the parameter-list. If the next token is a `,',
then we are at the end of this parameter. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
! {
! identifier = cp_parser_identifier (parser);
! /* Treat invalid names as if the parameter were nameless. */
! if (identifier == error_mark_node)
! identifier = NULL_TREE;
! }
else
identifier = NULL_TREE;
+
/* Create the template parameter. */
parameter = finish_template_template_parm (class_type_node,
identifier);
/* If the next token is an `=', then there is a
*************** cp_parser_type_parameter (cp_parser* par
*** 8229,8247 ****
else
default_argument = NULL_TREE;
/* Create the combined representation of the parameter and the
default argument. */
! parameter = build_tree_list (default_argument, parameter);
}
break;
default:
! /* Anything else is an error. */
! cp_parser_error (parser,
! "expected %<class%>, %<typename%>, or %<template%>");
! parameter = error_mark_node;
}
return parameter;
}
--- 8235,8251 ----
else
default_argument = NULL_TREE;
/* Create the combined representation of the parameter and the
default argument. */
! parameter = build_tree_list (default_argument, parameter);
}
break;
default:
! gcc_unreachable ();
! break;
}
return parameter;
}
*************** cp_parser_single_declaration (cp_parser*
*** 14799,14808 ****
--- 14803,14817 ----
int declares_class_or_enum;
tree decl = NULL_TREE;
cp_decl_specifier_seq decl_specifiers;
bool function_definition_p = false;
+ /* This function is only used when processing a template
+ declaration. */
+ gcc_assert (innermost_scope_kind () == sk_template_parms
+ || innermost_scope_kind () == sk_template_spec);
+
/* Defer access checks until we know what is being declared. */
push_deferring_access_checks (dk_deferred);
/* Try the `decl-specifier-seq [opt] init-declarator [opt]'
alternative. */
*************** cp_parser_single_declaration (cp_parser*
*** 14810,14819 ****
--- 14819,14836 ----
CP_PARSER_FLAGS_OPTIONAL,
&decl_specifiers,
&declares_class_or_enum);
if (friend_p)
*friend_p = cp_parser_friend_p (&decl_specifiers);
+
+ /* There are no template typedefs. */
+ if (decl_specifiers.specs[(int) ds_typedef])
+ {
+ error ("template declaration of %qs", "typedef");
+ decl = error_mark_node;
+ }
+
/* Gather up the access checks that occurred the
decl-specifier-seq. */
stop_deferring_access_checks ();
/* Check for the declaration of a template class. */
*************** cp_parser_single_declaration (cp_parser*
*** 14841,14852 ****
decl = TYPE_NAME (decl);
else
decl = error_mark_node;
}
}
- else
- decl = NULL_TREE;
/* If it's not a template class, try for a template function. If
the next token is a `;', then this declaration does not declare
anything. But, if there were errors in the decl-specifiers, then
the error might well have come from an attempted class-specifier.
In that case, there's no need to warn about a missing declarator. */
--- 14858,14867 ----
*************** cp_parser_single_declaration (cp_parser*
*** 14867,14877 ****
parser->scope = NULL_TREE;
parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE;
/* Look for a trailing `;' after the declaration. */
if (!function_definition_p
! && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
cp_parser_skip_to_end_of_block_or_statement (parser);
return decl;
}
--- 14882,14893 ----
parser->scope = NULL_TREE;
parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE;
/* Look for a trailing `;' after the declaration. */
if (!function_definition_p
! && (decl == error_mark_node
! || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))
cp_parser_skip_to_end_of_block_or_statement (parser);
return decl;
}
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.418
diff -c -5 -p -r1.418 tree.c
*** cp/tree.c 18 Oct 2004 17:21:28 -0000 1.418
--- cp/tree.c 3 Nov 2004 02:24:28 -0000
*************** pod_type_p (tree t)
*** 1714,1724 ****
return 1; /* pointer to non-member */
if (TYPE_PTR_TO_MEMBER_P (t))
return 1; /* pointer to member */
if (TREE_CODE (t) == VECTOR_TYPE)
! return 1; /* vectors are (small) arrays if scalars */
if (! CLASS_TYPE_P (t))
return 0; /* other non-class type (reference or function) */
if (CLASSTYPE_NON_POD_P (t))
return 0;
--- 1714,1724 ----
return 1; /* pointer to non-member */
if (TYPE_PTR_TO_MEMBER_P (t))
return 1; /* pointer to member */
if (TREE_CODE (t) == VECTOR_TYPE)
! return 1; /* vectors are (small) arrays of scalars */
if (! CLASS_TYPE_P (t))
return 0; /* other non-class type (reference or function) */
if (CLASSTYPE_NON_POD_P (t))
return 0;
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.591
diff -c -5 -p -r1.591 typeck.c
*** cp/typeck.c 1 Nov 2004 09:47:59 -0000 1.591
--- cp/typeck.c 3 Nov 2004 02:24:31 -0000
*************** build_const_cast_1 (tree dst_type, tree
*** 5097,5107 ****
}
tree
build_const_cast (tree type, tree expr)
{
! if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
if (processing_template_decl)
{
tree t = build_min (CONST_CAST_EXPR, type, expr);
--- 5097,5107 ----
}
tree
build_const_cast (tree type, tree expr)
{
! if (type == error_mark_node || error_operand_p (expr))
return error_mark_node;
if (processing_template_decl)
{
tree t = build_min (CONST_CAST_EXPR, type, expr);
Index: testsuite/g++.dg/conversion/const3.C
===================================================================
RCS file: testsuite/g++.dg/conversion/const3.C
diff -N testsuite/g++.dg/conversion/const3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/conversion/const3.C 3 Nov 2004 02:24:31 -0000
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/18177
+
+ void foo()
+ {
+ X; // { dg-error "" }
+ const_cast<int&>(X);
+ }
Index: testsuite/g++.dg/parse/crash13.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/parse/crash13.C,v
retrieving revision 1.2
diff -c -5 -p -r1.2 crash13.C
*** testsuite/g++.dg/parse/crash13.C 9 Mar 2004 08:16:49 -0000 1.2
--- testsuite/g++.dg/parse/crash13.C 3 Nov 2004 02:24:31 -0000
*************** struct A
*** 11,21 ****
{};
};
template <typename T>
void func(A<T>::B* ) // { dg-error "variable|template|expression" }
! { // { dg-error ";" }
}
int main()
{
func<void>(0); // { dg-error "not declared|expression|;" }
--- 11,21 ----
{};
};
template <typename T>
void func(A<T>::B* ) // { dg-error "variable|template|expression" }
! {
}
int main()
{
func<void>(0); // { dg-error "not declared|expression|;" }
Index: testsuite/g++.dg/template/crash25.C
===================================================================
RCS file: testsuite/g++.dg/template/crash25.C
diff -N testsuite/g++.dg/template/crash25.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/crash25.C 3 Nov 2004 02:24:31 -0000
***************
*** 0 ****
--- 1,3 ----
+ // PR c++/18124
+
+ template <template <int> class class> class A {}; // { dg-error "" }
Index: testsuite/g++.dg/template/typedef2.C
===================================================================
RCS file: testsuite/g++.dg/template/typedef2.C
diff -N testsuite/g++.dg/template/typedef2.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/typedef2.C 3 Nov 2004 02:24:31 -0000
***************
*** 0 ****
--- 1,3 ----
+ // PR c++/18155
+
+ template<int> typedef struct A; // { dg-error "" }
More information about the Gcc-patches
mailing list