From e3016344b3c8ca1ede6b31a8b9949998e5274cf7 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 31 Jan 2005 04:07:41 +0000 Subject: [PATCH] re PR c++/19395 (invalid scope qualifier allowed in typedef) PR c++/19395 * decl.c (grokdeclarator): Refactor code so that qualified names are never allowed as the declarator in a typedef. PR c++/19367 * name-lookup.c (do_nonmember_using_decl): Avoid overloading builtin declarations. PR c++/19395 * g++.dg/parse/error24.C: New test. PR c++/19367 * g++.dg/lookup/builtin1.C: New test. From-SVN: r94466 --- gcc/cp/ChangeLog | 8 ++++++ gcc/cp/decl.c | 20 +++++++-------- gcc/cp/name-lookup.c | 34 +++++++++++--------------- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/g++.dg/lookup/builtin1.C | 12 +++++++++ gcc/testsuite/g++.dg/parse/error24.C | 7 ++++++ 6 files changed, 57 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/builtin1.C create mode 100644 gcc/testsuite/g++.dg/parse/error24.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 19027354e19..0b1f7d1a3de 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2005-01-30 Mark Mitchell + PR c++/19395 + * decl.c (grokdeclarator): Refactor code so that qualified names + are never allowed as the declarator in a typedef. + + PR c++/19367 + * name-lookup.c (do_nonmember_using_decl): Avoid overloading + builtin declarations. + PR c++/19457 * call.c (convert_like_real): Inline call to dubious_conversion_warnings here. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f65427a8b1b..e2408e36b82 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7524,18 +7524,14 @@ grokdeclarator (const cp_declarator *declarator, TYPE_FOR_JAVA (type) = 1; if (decl_context == FIELD) - { - if (constructor_name_p (unqualified_id, current_class_type)) - pedwarn ("ISO C++ forbids nested type %qD with same name " - "as enclosing class", - unqualified_id); - decl = build_lang_decl (TYPE_DECL, unqualified_id, type); - } + decl = build_lang_decl (TYPE_DECL, unqualified_id, type); else + decl = build_decl (TYPE_DECL, unqualified_id, type); + if (id_declarator && declarator->u.id.qualifying_scope) + error ("%Jtypedef name may not be a nested-name-specifier", decl); + + if (decl_context != FIELD) { - decl = build_decl (TYPE_DECL, unqualified_id, type); - if (in_namespace || ctype) - error ("%Jtypedef name may not be a nested-name-specifier", decl); if (!current_function_decl) DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (current_function_decl) @@ -7547,6 +7543,10 @@ grokdeclarator (const cp_declarator *declarator, clones. */ DECL_ABSTRACT (decl) = 1; } + else if (constructor_name_p (unqualified_id, current_class_type)) + pedwarn ("ISO C++ forbids nested type %qD with same name " + "as enclosing class", + unqualified_id); /* If the user declares "typedef struct {...} foo" then the struct will have an anonymous name. Fill that name in now. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index bb40e53efa1..b72ded0903b 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2036,6 +2036,15 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype, oldval = NULL_TREE; } + /* It is impossible to overload a built-in function; any + explicit declaration eliminates the built-in declaration. + So, if OLDVAL is a built-in, then we can just pretend it + isn't there. */ + if (oldval + && TREE_CODE (oldval) == FUNCTION_DECL + && DECL_ANTICIPATED (oldval)) + oldval = NULL_TREE; + *newval = oldval; for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp)) { @@ -2059,33 +2068,18 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype, else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) { + gcc_assert (!DECL_ANTICIPATED (old_fn)); + /* There was already a non-using declaration in this scope with the same parameter types. If both are the same extern "C" functions, that's ok. */ if (decls_match (new_fn, old_fn)) - { - /* If the OLD_FN was a builtin, we've seen a real - declaration in another namespace. Use it instead. - Set tmp1 to NULL so we can use the existing - OVERLOAD logic at the end of this inner loop. - */ - if (DECL_ANTICIPATED (old_fn)) - { - gcc_assert (! DECL_ANTICIPATED (new_fn)); - tmp1 = NULL; - } - break; - } - else if (!DECL_ANTICIPATED (old_fn)) - { - /* If the OLD_FN was really declared, the - declarations don't match. */ + break; + else + { error ("%qD is already declared in this scope", name); break; } - - /* If the OLD_FN was not really there, just ignore - it and keep going. */ } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c90f67197ed..0d7f5306e9d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2005-01-30 Mark Mitchell + PR c++/19395 + * g++.dg/parse/error24.C: New test. + + PR c++/19367 + * g++.dg/lookup/builtin1.C: New test. + PR c++/19457 * g++.dg/warn/conv3.C: New test. diff --git a/gcc/testsuite/g++.dg/lookup/builtin1.C b/gcc/testsuite/g++.dg/lookup/builtin1.C new file mode 100644 index 00000000000..5f25f288965 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/builtin1.C @@ -0,0 +1,12 @@ +// PR c++/19367 +// { dg-do link } + +void abort (void) { throw 3; } + +namespace std { using ::abort; } + +int main () +{ + using std::abort; + abort(); +} diff --git a/gcc/testsuite/g++.dg/parse/error24.C b/gcc/testsuite/g++.dg/parse/error24.C new file mode 100644 index 00000000000..c0722504271 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error24.C @@ -0,0 +1,7 @@ +// PR c++/19395 + +struct A { + typedef int ::X; // { dg-error "" } +}; + +