diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5798,11 +5798,13 @@ "redeclaring non-static %0 as static is a Microsoft extension">, InGroup; def err_non_static_static : Error< - "non-static declaration of %0 follows static declaration">; + "non-static declaration of %0 follows static declaration;Please pick exactly one (static or non-static)">; +def err_extern_static : Error< + "extern declaration of %0 follows static declaration;Please pick exactly one (static or extern)">; def err_extern_non_extern : Error< - "extern declaration of %0 follows non-extern declaration">; + "extern declaration of %0 follows non-extern declaration;Please pick exactly one (non-extern or extern)">; def err_non_extern_extern : Error< - "non-extern declaration of %0 follows extern declaration">; + "non-extern declaration of %0 follows extern declaration;Please pick exactly one (extern or non-extern)">; 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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4637,6 +4637,15 @@ // the prior declaration. If no prior declaration is visible, or // if the prior declaration specifies no linkage, then the // identifier has external linkage. + + if (New->hasExternalStorage() && + Old->getCanonicalDecl()->getStorageClass() == SC_Static && + Old->isLocalVarDeclOrParm()) { + Diag(New->getLocation(), diag::err_extern_static) << New->getDeclName(); + Diag(OldLocation, PrevDiag); + return New->setInvalidDecl(); + } + if (New->hasExternalStorage() && Old->hasLinkage()) /* Okay */; else if (New->getCanonicalDecl()->getStorageClass() != SC_Static && diff --git a/clang/test/SemaCXX/extern_static.cpp b/clang/test/SemaCXX/extern_static.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/extern_static.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init +void f(void) +{ + static int x; // expected-note {{previous definition is here}} + extern int x; // expected-error {{extern declaration of 'x' follows static declaration;Please pick exactly one (static or extern)}} +} \ No newline at end of file