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). llvm-svn: 193671
This commit is contained in:
parent
60db142d86
commit
3876cc88ac
|
@ -337,6 +337,21 @@ void LookupResult::deletePaths(CXXBasePaths *Paths) {
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue