diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6a7fce8bebd..92c9ca421d5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2004-10-15 Mark Mitchell + + PR c++/17042 + * decl.c (declare_global_var): Use the return value from pushdecl. + + PR c++/14667 + * parser.c (cp_parser_simple_declaration): Do not diagnose invalid + type names if we have already found a valid type. + (cp_parser_member_declaration): Likewise. + + PR c++/17852 + * parser.c (cp_parser_member_specification_opt): Handle + CPP_PRAGMA. + 2004-10-15 Kazu Hirata * dump.c, g++spec.c, repo.c: Update copyright. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 054662d8708..00844fdbd0b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5029,7 +5029,11 @@ declare_global_var (tree name, tree type) TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; DECL_ARTIFICIAL (decl) = 1; - pushdecl (decl); + /* If the user has explicitly declared this variable (perhaps + because the code we are compiling is part of a low-level runtime + library), then it is possible that our declaration will be merged + with theirs by pushdecl. */ + decl = pushdecl (decl); cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0); pop_from_top_level (); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d914ed23d41..611a794d766 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6953,7 +6953,8 @@ cp_parser_simple_declaration (cp_parser* parser, T t; where "T" should name a type -- but does not. */ - if (cp_parser_parse_and_diagnose_invalid_type_name (parser)) + if (!decl_specifiers.type + && cp_parser_parse_and_diagnose_invalid_type_name (parser)) { /* If parsing tentatively, we should commit; we really are looking at a declaration. */ @@ -12880,6 +12881,13 @@ cp_parser_member_specification_opt (cp_parser* parser) break; default: + /* Accept #pragmas at class scope. */ + if (token->type == CPP_PRAGMA) + { + cp_lexer_handle_pragma (parser->lexer); + break; + } + /* Otherwise, the next construction must be a member-declaration. */ cp_parser_member_declaration (parser); @@ -12963,7 +12971,8 @@ cp_parser_member_declaration (cp_parser* parser) prefix_attributes = decl_specifiers.attributes; decl_specifiers.attributes = NULL_TREE; /* Check for an invalid type-name. */ - if (cp_parser_parse_and_diagnose_invalid_type_name (parser)) + if (!decl_specifiers.type + && cp_parser_parse_and_diagnose_invalid_type_name (parser)) return; /* If there is no declarator, then the decl-specifier-seq should specify a type. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf505a15cf5..4df9b8a0d23 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2004-10-15 Mark Mitchell + + PR c++/17042 + * g++.dg/init/dso_handle1.C: New test. + + PR c++/17852 + * g++.dg/parse/pragma1.C: New test. + + PR c++/14667 + * g++.dg/parse/typedef6.C: New test. + 2004-10-15 Aldy Hernandez * gcc.c-torture/execute/ieee/ieee.exp: Disable on powerpc-*-*spe. diff --git a/gcc/testsuite/g++.dg/init/dso_handle1.C b/gcc/testsuite/g++.dg/init/dso_handle1.C new file mode 100644 index 00000000000..6578f4fae7e --- /dev/null +++ b/gcc/testsuite/g++.dg/init/dso_handle1.C @@ -0,0 +1,10 @@ +// PR c++/17042 +// { dg-do assemble } +// { dg-options "-fuse-cxa-atexit" } + +struct A +{ A(); ~A(); }; +A a; +extern "C" { void* __dso_handle __attribute__ ((__weak__)); } +void f() +{ __dso_handle = 0; } diff --git a/gcc/testsuite/g++.dg/parse/pragma1.C b/gcc/testsuite/g++.dg/parse/pragma1.C new file mode 100644 index 00000000000..cdfd79caadb --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pragma1.C @@ -0,0 +1,8 @@ +// PR c++/17852 + +class T { +#pragma X + struct S { + }; +#pragma Y +}; diff --git a/gcc/testsuite/g++.dg/parse/typedef6.C b/gcc/testsuite/g++.dg/parse/typedef6.C new file mode 100644 index 00000000000..d3a39fc8586 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typedef6.C @@ -0,0 +1,6 @@ +// PR c++/14667 + +template +class Class1; + +class Class2 {} typedef Class1 Type1; // { dg-error "" }