From b2204f242a9622b24ca0136d46c17422ac65dd5e Mon Sep 17 00:00:00 2001 From: Argiris Kirtzidis Date: Mon, 31 Jan 2011 07:04:46 +0000 Subject: [PATCH] Diagnose if extern local variable is followed by non-extern and vice-versa. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124579 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ lib/Sema/SemaDecl.cpp | 14 ++++++++++++++ test/Sema/private-extern.c | 16 ++++++---------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7bec4c73d..47174b76b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index bcc67b2e9..24307c98a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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 diff --git a/test/Sema/private-extern.c b/test/Sema/private-extern.c index d3c126510..25591dc5b 100644 --- a/test/Sema/private-extern.c +++ b/test/Sema/private-extern.c @@ -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() { -- 2.11.4.GIT