From 825faf7a4faec8083b87ae2c98a1296991d161b5 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 29 Jun 2011 21:22:02 +0000 Subject: [PATCH] When redeclaring a local extern in the same scope, make sure that we replace the existing declaration appropriately. Patch by Jordy Rose, fixes PR10013 / . llvm-svn: 134097 --- clang/lib/Sema/SemaDecl.cpp | 14 ++++++++++++-- clang/test/Sema/extern-redecl.c | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2779faeb15cf..8069eb438594 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/test/Sema/extern-redecl.c b/clang/test/Sema/extern-redecl.c index 067e3c21e4c4..c176725df66b 100644 --- a/clang/test/Sema/extern-redecl.c +++ b/clang/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}} +} +