Skip to content

Commit

Permalink
Diagnose if extern local variable is followed by non-extern and vice-…
Browse files Browse the repository at this point in the history
…versa.

llvm-svn: 124579
  • Loading branch information
akyrtzi committed Jan 31, 2011
1 parent f41860c commit 819f610
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,10 @@ def err_static_non_static : Error<
"static declaration of %0 follows non-static declaration">;
def err_non_static_static : Error<
"non-static declaration of %0 follows static declaration">;
def err_extern_non_extern : Error<
"extern declaration of %0 follows non-extern declaration">;
def err_non_extern_extern : Error<
"non-extern declaration of %0 follows extern declaration">;
def err_non_thread_thread : Error<
"non-thread-local declaration of %0 follows thread-local declaration">;
def err_thread_non_thread : Error<
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,20 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
return New->setInvalidDecl();
}

// Check if extern is followed by non-extern and vice-versa.
if (New->hasExternalStorage() &&
!Old->hasLinkage() && Old->isLocalVarDecl()) {
Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return New->setInvalidDecl();
}
if (Old->hasExternalStorage() &&
!New->hasLinkage() && New->isLocalVarDecl()) {
Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return New->setInvalidDecl();
}

// Variables with external linkage are analyzed in FinalizeDeclaratorGroup.

// FIXME: The test for external storage here seems wrong? We still
Expand Down
16 changes: 6 additions & 10 deletions clang/test/Sema/private-extern.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,23 @@ __private_extern__ int g5; // expected-note{{previous definition}}
static int g5; // expected-error{{static declaration of 'g5' follows non-static declaration}}

void f0() {
// FIXME: Diagnose this?
int g6;
extern int g6;
int g6; // expected-note {{previous}}
extern int g6; // expected-error {{extern declaration of 'g6' follows non-extern declaration}}
}

void f1() {
// FIXME: Diagnose this?
int g7;
__private_extern__ int g7;
int g7; // expected-note {{previous}}
__private_extern__ int g7; // expected-error {{extern declaration of 'g7' follows non-extern declaration}}
}

void f2() {
extern int g8; // expected-note{{previous definition}}
// FIXME: Improve this diagnostic.
int g8; // expected-error{{redefinition of 'g8'}}
int g8; // expected-error {{non-extern declaration of 'g8' follows extern declaration}}
}

void f3() {
__private_extern__ int g9; // expected-note{{previous definition}}
// FIXME: Improve this diagnostic.
int g9; // expected-error{{redefinition of 'g9'}}
int g9; // expected-error {{non-extern declaration of 'g9' follows extern declaration}}
}

void f4() {
Expand Down

0 comments on commit 819f610

Please sign in to comment.