Fixes a corner case bug whereby declaring and defining an extern variable in a

particular sequence causes its definition to not be generated in the object file.
(fixes radar 8071804).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106424 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2010-06-21 16:08:37 +00:00
Родитель 5bf1bdc2fe
Коммит 2bf6d7b1f7
4 изменённых файлов: 52 добавлений и 3 удалений

Просмотреть файл

@ -701,7 +701,15 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
// AST for 'extern "C" int foo;' is annotated with 'extern'.
if (hasExternalStorage())
return DeclarationOnly;
if (getStorageClassAsWritten() == Extern ||
getStorageClassAsWritten() == PrivateExtern) {
for (const VarDecl *PrevVar = getPreviousDeclaration();
PrevVar; PrevVar = PrevVar->getPreviousDeclaration()) {
if (PrevVar->getLinkage() == InternalLinkage && PrevVar->hasInit())
return DeclarationOnly;
}
}
// C99 6.9.2p2:
// A declaration of an object that has file scope without an initializer,
// and without a storage class specifier or the scs 'static', constitutes

Просмотреть файл

@ -1455,6 +1455,10 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
return;
}
if (New->hasExternalStorage() &&
Old->getLinkage() == InternalLinkage)
New->setStorageClass(Old->getStorageClass());
// Keep a chain of previous declarations.
New->setPreviousDeclaration(Old);

Просмотреть файл

@ -17,3 +17,40 @@ Anon anon1;
// CHECK: @anon2 = internal global
X<Anon> anon2;
// rdar: // 8071804
char const * const xyzzy = "Hello, world!";
extern char const * const xyzzy;
char const * const *test1()
{
// CHECK: @_ZL5xyzzy = internal constant
return &xyzzy;
}
static char const * const static_xyzzy = "Hello, world!";
extern char const * const static_xyzzy;
char const * const *test2()
{
// CHECK: @_ZL12static_xyzzy = internal constant
return &static_xyzzy;
}
static char const * static_nonconst_xyzzy = "Hello, world!";
extern char const * static_nonconst_xyzzy;
char const * *test3()
{
// CHECK: @_ZL21static_nonconst_xyzzy = internal global
return &static_nonconst_xyzzy;
}
char const * extern_nonconst_xyzzy = "Hello, world!";
extern char const * extern_nonconst_xyzzy;
char const * *test4()
{
// CHECK: @extern_nonconst_xyzzy = global
return &extern_nonconst_xyzzy;
}

Просмотреть файл

@ -58,5 +58,5 @@ int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}} \
// PR3645
static int a;
extern int a;
int a;
extern int a; // expected-note {{previous definition is here}}
int a; // expected-error {{non-static declaration of 'a' follows static declaration}}