diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2005-06-13 15:58:10 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2005-06-13 15:58:10 +0000 |
commit | 8fe4d24bebd6df659ab43ad5dd065a29c473f815 (patch) | |
tree | 80df738d7463c3986a421395691d3add01541ee2 /gcc | |
parent | 56fc483e31987c2936dfee9e141702c848da7a50 (diff) | |
download | gcc-8fe4d24bebd6df659ab43ad5dd065a29c473f815.zip gcc-8fe4d24bebd6df659ab43ad5dd065a29c473f815.tar.gz gcc-8fe4d24bebd6df659ab43ad5dd065a29c473f815.tar.bz2 |
re PR c++/20789 (ICE with incomplete type in template)
cp:
PR c++/20789
* decl.c (cp_finish_decl): Clear runtime runtime initialization if
in-class decl's initializer is bad.
PR c++/21929
* parser.c (struct cp_parser): Document that scope could be
error_mark.
(cp_parser_diagnose_invalid_type_name): Cope with error_mark for
scope.
(cp_parser_nested_name_specifier): Return NULL_TREE on error.
(cp_parser_postfix_expression): Deal with null or error_mark
scope.
(cp_parser_elaborated_type_specifier): Adjust
cp_parser_nested_name_specifier call.
* parser (cp_parser_skip_to_end_of_block_or_statement): Cleanup.
testsuite:
PR c++/21929
* g++.dg/parse/crash26.C: New.
PR c++/20789
* g++.dg/init/member1.C: New.
From-SVN: r100880
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/decl.c | 10 | ||||
-rw-r--r-- | gcc/cp/parser.c | 75 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/member1.C | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/crash26.C | 12 |
6 files changed, 109 insertions, 33 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fa37b36..00a029d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2005-06-13 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/20789 + * decl.c (cp_finish_decl): Clear runtime runtime initialization if + in-class decl's initializer is bad. + + PR c++/21929 + * parser.c (struct cp_parser): Document that scope could be + error_mark. + (cp_parser_diagnose_invalid_type_name): Cope with error_mark for + scope. + (cp_parser_nested_name_specifier): Return NULL_TREE on error. + (cp_parser_postfix_expression): Deal with null or error_mark + scope. + (cp_parser_elaborated_type_specifier): Adjust + cp_parser_nested_name_specifier call. + + * parser (cp_parser_skip_to_end_of_block_or_statement): Cleanup. + 2005-06-12 Roger Sayle <roger@eyesopen.com> PR c++/21930 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6b278ae..c17d6f8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4834,6 +4834,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) "initialized", decl); init = NULL_TREE; } + if (DECL_EXTERNAL (decl) && init) + { + /* The static data member cannot be initialized by a + non-constant when being declared. */ + error ("%qD cannot be initialized by a non-constant expression" + " when being declared", decl); + DECL_INITIALIZED_IN_CLASS_P (decl) = 0; + init = NULL_TREE; + } + /* Handle: [dcl.init] diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cb389d2..f56c901 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1217,7 +1217,8 @@ typedef struct cp_parser GTY(()) /* The scope in which names should be looked up. If NULL_TREE, then we look up names in the scope that is currently open in the source program. If non-NULL, this is either a TYPE or - NAMESPACE_DECL for the scope in which we should look. + NAMESPACE_DECL for the scope in which we should look. It can + also be ERROR_MARK, when we've parsed a bogus scope. This value is not cleared automatically after a name is looked up, so we must be careful to clear it before starting a new look @@ -1225,7 +1226,7 @@ typedef struct cp_parser GTY(()) will look up `Z' in the scope of `X', rather than the current scope.) Unfortunately, it is difficult to tell when name lookup is complete, because we sometimes peek at a token, look it up, - and then decide not to consume it. */ + and then decide not to consume it. */ tree scope; /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the @@ -2045,7 +2046,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id) if (TREE_CODE (decl) == TEMPLATE_DECL) error ("invalid use of template-name %qE without an argument list", decl); - else if (!parser->scope) + else if (!parser->scope || parser->scope == error_mark_node) { /* Issue an error message. */ error ("%qE does not name a type", id); @@ -2313,36 +2314,48 @@ cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser) static void cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser) { - unsigned nesting_depth = 0; + int nesting_depth = 0; - while (true) + while (nesting_depth >= 0) { - cp_token *token; - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* If we've run out of tokens, stop. */ + cp_token *token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_EOF) break; - /* If the next token is a `;', we have reached the end of the - statement. */ - if (token->type == CPP_SEMICOLON && !nesting_depth) + + switch (token->type) { - /* Consume the `;'. */ - cp_lexer_consume_token (parser->lexer); + case CPP_EOF: + /* If we've run out of tokens, stop. */ + nesting_depth = -1; + continue; + + case CPP_SEMICOLON: + /* Stop if this is an unnested ';'. */ + if (!nesting_depth) + nesting_depth = -1; + break; + + case CPP_CLOSE_BRACE: + /* Stop if this is an unnested '}', or closes the outermost + nesting level. */ + nesting_depth--; + if (!nesting_depth) + nesting_depth = -1; + break; + + case CPP_OPEN_BRACE: + /* Nest. */ + nesting_depth++; + break; + + default: break; } + /* Consume the token. */ - token = cp_lexer_consume_token (parser->lexer); - /* If the next token is a non-nested `}', then we have reached - the end of the current block. */ - if (token->type == CPP_CLOSE_BRACE - && (nesting_depth == 0 || --nesting_depth == 0)) - break; - /* If it the next token is a `{', then we are entering a new - block. Consume the entire block. */ - if (token->type == CPP_OPEN_BRACE) - ++nesting_depth; + cp_lexer_consume_token (parser->lexer); + } } @@ -3664,9 +3677,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, /* Parse a nested-name-specifier. See cp_parser_nested_name_specifier_opt for details. This function behaves identically, except that it will an issue an error if no - nested-name-specifier is present, and it will return - ERROR_MARK_NODE, rather than NULL_TREE, if no nested-name-specifier - is present. */ + nested-name-specifier is present. */ static tree cp_parser_nested_name_specifier (cp_parser *parser, @@ -3688,7 +3699,6 @@ cp_parser_nested_name_specifier (cp_parser *parser, { cp_parser_error (parser, "expected nested-name-specifier"); parser->scope = NULL_TREE; - return error_mark_node; } return scope; @@ -3973,7 +3983,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p) id = cp_parser_identifier (parser); /* Don't process id if nested name specifier is invalid. */ - if (scope == error_mark_node) + if (!scope || scope == error_mark_node) return error_mark_node; /* If we look up a template-id in a non-dependent qualifying scope, there's no need to create a dependent type. */ @@ -9871,12 +9881,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, /* Look for the nested-name-specifier. */ if (tag_type == typename_type) { - if (cp_parser_nested_name_specifier (parser, + if (!cp_parser_nested_name_specifier (parser, /*typename_keyword_p=*/true, /*check_dependency_p=*/true, /*type_p=*/true, - is_declaration) - == error_mark_node) + is_declaration)) return error_mark_node; } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af6d1b1..8fb457e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-06-13 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/21929 + * g++.dg/parse/crash26.C: New. + + PR c++/20789 + * g++.dg/init/member1.C: New. + 2005-06-13 Jakub Jelinek <jakub@redhat.com> * gfortran.dg/altreturn_1.f90: New test. diff --git a/gcc/testsuite/g++.dg/init/member1.C b/gcc/testsuite/g++.dg/init/member1.C new file mode 100644 index 0000000..1c89d5a --- /dev/null +++ b/gcc/testsuite/g++.dg/init/member1.C @@ -0,0 +1,18 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 13 Jun 2005 <nathan@codesourcery.com> + +// Origin: Ivan Godard <igodard@pacbell.net> +// Bug 20789: ICE on invalid + +template<typename> struct A; + +template<int> struct B {}; + +template<typename T> struct C +{ + static const int i = A<T>::i; // { dg-error "incomplete" } + static const int j = i; // { dg-error "initialized by a non-const" } + B<j> b; // { dg-error "not a valid template arg" } +}; + +C<int> c; diff --git a/gcc/testsuite/g++.dg/parse/crash26.C b/gcc/testsuite/g++.dg/parse/crash26.C new file mode 100644 index 0000000..2b4f165 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash26.C @@ -0,0 +1,12 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 13 Jun 2005 <nathan@codesourcery.com> + +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> +// Bug 21929: ICE on invalid + +template<int> struct A +{ + struct B; +}; + +template<> struct A<void>::B {}; // { dg-error "mismatch|expected|name a type|extra" } |