aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp14
-rw-r--r--test/Sema/extern-redecl.c15
2 files changed, 26 insertions, 3 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2779faeb15..8069eb4385 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3299,8 +3299,18 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
if (S && IdResolver.ReplaceDecl(PrevDecl, ND)) {
// The previous declaration was found on the identifer resolver
// chain, so remove it from its scope.
- while (S && !S->isDeclScope(PrevDecl))
- S = S->getParent();
+
+ if (S->isDeclScope(PrevDecl)) {
+ // Special case for redeclarations in the SAME scope.
+ // Because this declaration is going to be added to the identifier chain
+ // later, we should temporarily take it OFF the chain.
+ IdResolver.RemoveDecl(ND);
+
+ } else {
+ // Find the scope for the original declaration.
+ while (S && !S->isDeclScope(PrevDecl))
+ S = S->getParent();
+ }
if (S)
S->RemoveDecl(PrevDecl);
diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c
index 067e3c21e4..c176725df6 100644
--- a/test/Sema/extern-redecl.c
+++ b/test/Sema/extern-redecl.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
// rdar: // 8125274
static int a16[]; // expected-warning {{tentative array definition assumed to have one element}}
@@ -7,3 +7,16 @@ void f16(void) {
extern int a16[];
}
+
+// PR10013: Scope of extern declarations extend past enclosing block
+extern int PR10013_x;
+int PR10013(void) {
+ int *PR10013_x = 0;
+ {
+ extern int PR10013_x;
+ extern int PR10013_x;
+ }
+
+ return PR10013_x; // expected-warning{{incompatible pointer to integer conversion}}
+}
+