Hi rsmith,
Hi Richard,
I attempted to implement a patch to fix [temp.local] p7 which states as -
"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)."
Clang incorrectly compiles the test code updated in this revision as the name
lookup finds the 'U' as member of the template class instead of taking it as
the template parameter.
This was also discussed at
http://clang-developers.42468.n3.nabble.com/Name-lookup-of-class-member-vs-template-parameter-td4036312.html
What we have tried to do here is detect if we are inside a class scope in
member of a class template and set the semacontext to the same so that name
lookup should continue searching in this semantic context.
I also had a doubt here it would be great if you could clarify the same -
Isnt the above rule applicable even if we have something like -
template<class B> struct C {
struct U { typedef int X; };
template<class U>
struct D;
};
template<class B>
template<class U>
struct C<B>::D {
void f() {
typename U::X r; // expected-error {{type 'double' cannot be used prior
to '::' because it has no members}}
}
};
C<int>::D<double> y; // expected-note {{in instantiation of template class
'C<int>::D<double>' requested here}}
i.e. we have a definition outside of the class template and a function defined
inside it which uses the parameter 'U' in this case shouldnt we take 'U' as the
template parameter? Both clang and gcc 4.8.1 compiles this code. But as per
standard this seems wrong. Am i correct here or i'm missing something?
I'm a bit new to template implementation in compilers. It would be great if you
could let me know if this is the right direction to fix this issue and guide us
through this bug.
Thanks
Karthik
http://llvm-reviews.chandlerc.com/D2327
Files:
lib/Sema/SemaLookup.cpp
test/CXX/temp/temp.res/temp.local/p7.cpp
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -849,8 +849,11 @@
// Find the namespace context in which the original scope occurs. In
// the example, this is namespace N.
DeclContext *Semantic = DC;
- while (!Semantic->isFileContext())
+ while (!Semantic->isFileContext()) {
Semantic = Semantic->getParent();
+ if (S->isClassScope())
+ break;
+ }
// Find the declaration context just outside of the template
// parameter scope. This is the context in which the template is
Index: test/CXX/temp/temp.res/temp.local/p7.cpp
===================================================================
--- test/CXX/temp/temp.res/temp.local/p7.cpp
+++ test/CXX/temp/temp.res/temp.local/p7.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
template<class T> struct A {
int B;
@@ -9,3 +8,22 @@
template<class B> int A<B>::f() {
return B;
}
+
+struct A1 {
+ struct B { typedef int X; };
+};
+
+template<class B> struct C : A1 {
+ B::X q; // Ok: A1::B.
+ struct U { typedef int X; };
+ template<class U>
+ struct D;
+};
+
+template<class B>
+template<class U>
+struct C<B>::D {
+ typename U::X r; // expected-error {{type 'double' cannot be used prior to
'::' because it has no members}}
+};
+
+C<int>::D<double> y; // expected-note {{in instantiation of template class
'C<int>::D<double>' requested here}}
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -849,8 +849,11 @@
// Find the namespace context in which the original scope occurs. In
// the example, this is namespace N.
DeclContext *Semantic = DC;
- while (!Semantic->isFileContext())
+ while (!Semantic->isFileContext()) {
Semantic = Semantic->getParent();
+ if (S->isClassScope())
+ break;
+ }
// Find the declaration context just outside of the template
// parameter scope. This is the context in which the template is
Index: test/CXX/temp/temp.res/temp.local/p7.cpp
===================================================================
--- test/CXX/temp/temp.res/temp.local/p7.cpp
+++ test/CXX/temp/temp.res/temp.local/p7.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
template<class T> struct A {
int B;
@@ -9,3 +8,22 @@
template<class B> int A<B>::f() {
return B;
}
+
+struct A1 {
+ struct B { typedef int X; };
+};
+
+template<class B> struct C : A1 {
+ B::X q; // Ok: A1::B.
+ struct U { typedef int X; };
+ template<class U>
+ struct D;
+};
+
+template<class B>
+template<class U>
+struct C<B>::D {
+ typename U::X r; // expected-error {{type 'double' cannot be used prior to '::' because it has no members}}
+};
+
+C<int>::D<double> y; // expected-note {{in instantiation of template class 'C<int>::D<double>' requested here}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits