r193671 - PR17731: When determining whether a tag and a non-tag were declared in the same

Richard Smith richard-llvm at metafoo.co.uk
Tue Oct 29 18:02:04 PDT 2013


Author: rsmith
Date: Tue Oct 29 20:02:04 2013
New Revision: 193671

URL: http://llvm.org/viewvc/llvm-project?rev=193671&view=rev
Log:
PR17731: When determining whether a tag and a non-tag were declared in the same
scope, be careful about function-scope declarations (which are not declared in
their semantic context).

Modified:
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=193671&r1=193670&r2=193671&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Oct 29 20:02:04 2013
@@ -337,6 +337,21 @@ void LookupResult::deletePaths(CXXBasePa
   delete Paths;
 }
 
+/// Get a representative context for a declaration such that two declarations
+/// will have the same context if they were found within the same scope.
+DeclContext *getContextForScopeMatching(Decl *D) {
+  // For function-local declarations, use that function as the context. This
+  // doesn't account for scopes within the function; the caller must deal with
+  // those.
+  DeclContext *DC = D->getLexicalDeclContext();
+  if (DC->isFunctionOrMethod())
+    return DC;
+
+  // Otherwise, look at the semantic context of the declaration. The
+  // declaration must have been found there.
+  return D->getDeclContext()->getRedeclContext();
+}
+
 /// Resolves the result kind of this lookup.
 void LookupResult::resolveKind() {
   unsigned N = Decls.size();
@@ -437,8 +452,8 @@ void LookupResult::resolveKind() {
   // even if they're not visible. (ref?)
   if (HideTags && HasTag && !Ambiguous &&
       (HasFunction || HasNonFunction || HasUnresolved)) {
-    if (Decls[UniqueTagIndex]->getDeclContext()->getRedeclContext()->Equals(
-         Decls[UniqueTagIndex? 0 : N-1]->getDeclContext()->getRedeclContext()))
+    if (getContextForScopeMatching(Decls[UniqueTagIndex])->Equals(
+            getContextForScopeMatching(Decls[UniqueTagIndex ? 0 : N - 1])))
       Decls[UniqueTagIndex] = Decls[--N];
     else
       Ambiguous = true;

Modified: cfe/trunk/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp?rev=193671&r1=193670&r2=193671&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp Tue Oct 29 20:02:04 2013
@@ -22,3 +22,48 @@ void f() {
   Y(1); // okay
 }
 
+namespace PR17731 {
+  void f() {
+    struct S { S() {} };
+    int S(void);
+    int a = S();
+    struct S b;
+    {
+      int S(void);
+      int a = S();
+      struct S c = b;
+    }
+    {
+      struct S { S() {} }; // expected-note {{candidate}}
+      int a = S(); // expected-error {{no viable conversion from 'S'}}
+      struct S c = b; // expected-error {{no viable conversion from 'struct S'}}
+    }
+  }
+  void g() {
+    int S(void);
+    struct S { S() {} };
+    int a = S();
+    struct S b;
+    {
+      int S(void);
+      int a = S();
+      struct S c = b;
+    }
+    {
+      struct S { S() {} }; // expected-note {{candidate}}
+      int a = S(); // expected-error {{no viable conversion from 'S'}}
+      struct S c = b; // expected-error {{no viable conversion from 'struct S'}}
+    }
+  }
+
+  struct A {
+    struct B;
+    void f();
+    int B;
+  };
+  struct A::B {};
+  void A::f() {
+    B = 123;
+    struct B b;
+  }
+}





More information about the cfe-commits mailing list