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