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
This commit is contained in:
Mark Mitchell 2005-01-31 04:07:41 +00:00 committed by Mark Mitchell
parent 8c55a142cd
commit e3016344b3
6 changed files with 57 additions and 30 deletions

View File

@ -1,5 +1,13 @@
2005-01-30 Mark Mitchell <mark@codesourcery.com>
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.

View File

@ -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.

View File

@ -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. */
}
}

View File

@ -1,5 +1,11 @@
2005-01-30 Mark Mitchell <mark@codesourcery.com>
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.

View File

@ -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();
}

View File

@ -0,0 +1,7 @@
// PR c++/19395
struct A {
typedef int ::X; // { dg-error "" }
};