[cfe-commits] r127623 - in /cfe/trunk: include/clang/Sema/IdentifierResolver.h lib/Sema/IdentifierResolver.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/goto.cpp

Douglas Gregor dgregor at apple.com
Mon Mar 14 14:19:51 PDT 2011


Author: dgregor
Date: Mon Mar 14 16:19:51 2011
New Revision: 127623

URL: http://llvm.org/viewvc/llvm-project?rev=127623&view=rev
Log:
When synthesizing a label declaration based on a goto statement that
cannot yet be resolved, be sure to push the new label declaration into
the right place within the identifier chain. Otherwise, name lookup in
C++ gets confused when searching for names that are lexically closer
than the label. Fixes PR9463.

Added:
    cfe/trunk/test/SemaCXX/goto.cpp
Modified:
    cfe/trunk/include/clang/Sema/IdentifierResolver.h
    cfe/trunk/lib/Sema/IdentifierResolver.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/include/clang/Sema/IdentifierResolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/IdentifierResolver.h?rev=127623&r1=127622&r2=127623&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/IdentifierResolver.h (original)
+++ cfe/trunk/include/clang/Sema/IdentifierResolver.h Mon Mar 14 16:19:51 2011
@@ -53,6 +53,11 @@
     /// declaration was not found, returns false.
     bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
 
+    /// \brief Insert the given declaration at the given position in the list.
+    void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
+      Decls.insert(Pos, D);
+    }
+                    
   private:
     DeclsTy Decls;
   };
@@ -166,6 +171,10 @@
   /// (and, therefore, replaced).
   bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
 
+  /// \brief Insert the given declaration prior to the given iterator
+  /// position
+  void InsertDecl(iterator Pos, NamedDecl *D);
+
   /// \brief Link the declaration into the chain of declarations for
   /// the given identifier.
   ///

Modified: cfe/trunk/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.cpp?rev=127623&r1=127622&r2=127623&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.cpp Mon Mar 14 16:19:51 2011
@@ -168,6 +168,39 @@
   IDI->AddDecl(D);
 }
 
+void IdentifierResolver::InsertDecl(iterator Pos, NamedDecl *D) {
+  if (Pos == iterator()) {
+    // Simple case: insert at the beginning of the list (which is the
+    // end of the stored vector).
+    AddDecl(D);
+    return;
+  }
+  
+  DeclarationName Name = D->getDeclName();
+  void *Ptr = Name.getFETokenInfo<void>();
+  
+  if (isDeclPtr(Ptr)) {
+    // There's only one element, and we want to insert before it in the list.
+    // Just create the storage for these identifiers and insert them in the
+    // opposite order we normally would.
+    assert(isDeclPtr(Ptr) && "Not a single declaration!");
+    Name.setFETokenInfo(NULL);
+    IdDeclInfo *IDI = &(*IdDeclInfos)[Name];
+    NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
+    IDI->AddDecl(D);
+    IDI->AddDecl(PrevD);
+    return;
+  }
+
+  // General case: insert the declaration at the appropriate point in the 
+  // list, which already has at least two elements.
+  IdDeclInfo *IDI = toIdDeclInfo(Ptr);
+  if (Pos.isIterator())
+    IDI->InsertDecl(Pos.getIterator(), D);
+  else
+    IDI->InsertDecl(IDI->decls_begin(), D);
+}
+
 /// RemoveDecl - Unlink the decl from its shadowed decl chain.
 /// The decl must already be part of the decl chain.
 void IdentifierResolver::RemoveDecl(NamedDecl *D) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=127623&r1=127622&r2=127623&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Mar 14 16:19:51 2011
@@ -494,7 +494,20 @@
   }
 
   S->AddDecl(D);
-  IdResolver.AddDecl(D);
+  
+  if (isa<LabelDecl>(D) && !cast<LabelDecl>(D)->isGnuLocal()) {
+    // Implicitly-generated labels may end up getting generated in an order that
+    // isn't strictly lexical, which breaks name lookup. Be careful to insert
+    // the label at the appropriate place in the identifier chain.
+    for (I = IdResolver.begin(D->getDeclName()); I != IEnd; ++I) {
+      if ((*I)->getLexicalDeclContext()->Encloses(CurContext))
+        break;
+    }
+    
+    IdResolver.InsertDecl(I, D);
+  } else {
+    IdResolver.AddDecl(D);
+  }
 }
 
 bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S,

Added: cfe/trunk/test/SemaCXX/goto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/goto.cpp?rev=127623&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/goto.cpp (added)
+++ cfe/trunk/test/SemaCXX/goto.cpp Mon Mar 14 16:19:51 2011
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR9463
+double *end;
+void f() {
+  {
+    int end = 0;
+    goto end;
+    end = 1;
+  }
+
+ end:
+  return;
+}
+
+void g() {
+  end = 1; // expected-error{{assigning to 'double *' from incompatible type 'int'}}
+}





More information about the cfe-commits mailing list