re PR c++/27227 (rejects valid code with some extern "C")
PR c++/27227 * decl.c (decls_match): Allow an extern "C" variable declarations from different namespaces to match. (duplicate_decls): Disallow redeclaring a variable with a different linkage specification. PR c++/27227 * g++.dg/lookup/linkage1.C: New test. * g++.dg/lookup/linkage2.C: Likewise. From-SVN: r114647
This commit is contained in:
parent
c3b11a40d0
commit
ace4831de9
|
@ -1,3 +1,11 @@
|
|||
2006-06-13 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/27227
|
||||
* decl.c (decls_match): Allow an extern "C" variable declarations
|
||||
from different namespaces to match.
|
||||
(duplicate_decls): Disallow redeclaring a variable with a
|
||||
different linkage specification.
|
||||
|
||||
2006-06-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/27793
|
||||
|
|
|
@ -999,7 +999,13 @@ decls_match (tree newdecl, tree olddecl)
|
|||
/* Need to check scope for variable declaration (VAR_DECL).
|
||||
For typedef (TYPE_DECL), scope is ignored. */
|
||||
if (TREE_CODE (newdecl) == VAR_DECL
|
||||
&& CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
|
||||
&& CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
|
||||
/* [dcl.link]
|
||||
Two declarations for an object with C language linkage
|
||||
with the same name (ignoring the namespace that qualify
|
||||
it) that appear in different namespace scopes refer to
|
||||
the same object. */
|
||||
&& !(DECL_EXTERN_C_P (olddecl) && DECL_EXTERN_C_P (newdecl)))
|
||||
return 0;
|
||||
|
||||
if (TREE_TYPE (newdecl) == error_mark_node)
|
||||
|
@ -1453,14 +1459,42 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
|||
warning (0, "prototype for %q+#D", newdecl);
|
||||
warning (0, "%Jfollows non-prototype definition here", olddecl);
|
||||
}
|
||||
else if (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
else if ((TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
|| TREE_CODE (olddecl) == VAR_DECL)
|
||||
&& DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
|
||||
{
|
||||
/* extern "C" int foo ();
|
||||
int foo () { bar (); }
|
||||
is OK. */
|
||||
/* [dcl.link]
|
||||
If two declarations of the same function or object
|
||||
specify different linkage-specifications ..., the program
|
||||
is ill-formed.... Except for functions with C++ linkage,
|
||||
a function declaration without a linkage specification
|
||||
shall not precede the first linkage specification for
|
||||
that function. A function can be declared without a
|
||||
linkage specification after an explicit linkage
|
||||
specification has been seen; the linkage explicitly
|
||||
specified in the earlier declaration is not affected by
|
||||
such a function declaration.
|
||||
|
||||
DR 563 raises the question why the restrictions on
|
||||
functions should not also apply to objects. Older
|
||||
versions of G++ silently ignore the linkage-specification
|
||||
for this example:
|
||||
|
||||
namespace N {
|
||||
extern int i;
|
||||
extern "C" int i;
|
||||
}
|
||||
|
||||
which is clearly wrong. Therefore, we now treat objects
|
||||
like functions. */
|
||||
if (current_lang_depth () == 0)
|
||||
SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
|
||||
{
|
||||
/* There is no explicit linkage-specification, so we use
|
||||
the linkage from the previous declaration. */
|
||||
if (!DECL_LANG_SPECIFIC (newdecl))
|
||||
retrofit_lang_decl (newdecl);
|
||||
SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("previous declaration of %q+#D with %qL linkage",
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2006-06-14 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/27227
|
||||
* g++.dg/lookup/linkage1.C: New test.
|
||||
* g++.dg/lookup/linkage2.C: Likewise.
|
||||
|
||||
2006-06-14 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
PR middle-end/27959
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
// DR 563
|
||||
|
||||
extern int i; // { dg-error "linkage" }
|
||||
extern "C" int i; // { dg-error "linkage" }
|
|
@ -0,0 +1,7 @@
|
|||
// PR c++/27227
|
||||
|
||||
namespace x {
|
||||
extern "C" const int y;
|
||||
}
|
||||
using x::y;
|
||||
extern "C" int const y=0;
|
Loading…
Reference in New Issue