Name lookup of class member vs template parameter

Hi all,

This is with respect to the following test case:

struct A {
struct B { typedef int X; };
};

template struct C : A {
B::X q; // Ok: A::B.
struct U { typedef int X; };
template
struct D;
};

template
template
struct C::smiley: {
typename U::X r; // { dg-error “” }
};

C::smiley: y;

As far as I am able to make out, this code compiles fine with Clang, because the statement typename U::X r; resolves for U by looking up the class members first and than the template parameter list.

But isnt it supposed to throw an error based on the following wordings from the standard (The wordings in the bracket are of interest to us):

In the definition of a member of a class template that appears outside of the class template definition, the name of a member of the class template hides the name of a template-parameter of any enclosing class templates (but not a template-parameter of the member if the member is a class or function template).

Note: The below mentioned example is from the standards.

Example:

template struct A {
struct B { /* … */ };
typedef void C;
void f();
template void g(U);
};

template void A::f() {
B b; // A’s B, not the template parameter
}

template template void A::g(C) {
B b; // A’s B, not the template parameter
C c; // the template parameter C, not A’s C , this is the case I suppose we are not handling
}

Am I missing something in my analysis or is this a potential bug??

Inputs on this would be really helpful.

Thanks,
Rahul

Hi all,

This is with respect to the following test case:

struct A {
    struct B { typedef int X; };
};

template<class B> struct C : A {
    B::X q; // Ok: A::B.
    struct U { typedef int X; };
    template<class U>
        struct D;
};

template<class B>
template<class U>
struct C<B>::smiley: {
    typename U::X r; // { dg-error "" }
};

C<int>::D<double> y;

As far as I am able to make out, this code compiles fine with Clang,
because the statement typename U::X r; resolves for U by looking up the
class members first and than the template parameter list.

But isnt it supposed to throw an error based on the following wordings
from the standard (The wordings in the bracket are of interest to us):

In the definition of a member of a class template that appears outside of
the class template definition, the name of a member of the class template
hides the name of a template-parameter of any enclosing class templates
(but not a template-parameter of the member if the member is a class or
function template).

Note: The below mentioned example is from the standards.

Example:

template<class T> struct A {
struct B { /* ... */ };
typedef void C;
void f();
template<class U> void g(U);
};

template<class B> void A<B>::f() {
B b; // A’s B, not the template parameter
}

template<class B> template<class C> void A<B>::g(C) {
B b; // A’s B, not the template parameter
C c; // the template parameter C, not A’s C , this is the case I suppose
we are not handling
}

Am I missing something in my analysis or is this a potential bug??

Yes, this is a bug.

Thanks Richard.

I have been analyzing the code so as to find a way to fix this.
I suppose the function needs to add a check for the same.

static std::pair<DeclContext *, bool> findOuterContext(Scope *S);

Can you give me a few pointers on how to approach fixing this bug?

Thanks,
Rahul