[cfe-commits] r105518 - in /cfe/trunk: docs/UsersManual.html include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
Jeffrey Yasskin
jyasskin at google.com
Fri Jun 4 18:39:57 PDT 2010
Author: jyasskin
Date: Fri Jun 4 20:39:57 2010
New Revision: 105518
URL: http://llvm.org/viewvc/llvm-project?rev=105518&view=rev
Log:
Add an extension to avoid an error when a global template has the same name as
a member template, and you try to call the member template with an explicit
template argument. See PR7247
For example, this downgrades the error to a warning in:
template<typename T> struct set{};
struct Value {
template<typename T>
void set(T value) {
}
};
void foo() {
Value v;
v.set<double>(3.2); // Warning here.
}
Added:
cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
Modified:
cfe/trunk/docs/UsersManual.html
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/docs/UsersManual.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.html?rev=105518&r1=105517&r2=105518&view=diff
==============================================================================
--- cfe/trunk/docs/UsersManual.html (original)
+++ cfe/trunk/docs/UsersManual.html Fri Jun 4 20:39:57 2010
@@ -386,6 +386,30 @@
and <a href="">-Wbaz</a>.</p>
</dd>
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_Wambiguous-member-template"><b>-Wambiguous-member-template</b>:
+Warn about unqualified uses of a member template whose name resolves
+to another template at the location of the use.</dt>
+<dd>This option, which defaults to on, enables a warning in the
+following code:</p>
+
+<pre>
+template<typename T> struct set{};
+template<typename T> struct trait { typedef const T& type; };
+struct Value {
+ template<typename T> void set(typename trait<T>::type value) {}
+};
+void foo() {
+ Value v;
+ v.set<double>(3.2);
+}
+</pre>
+
+<p>C++ [basic.lookup.classref] requires this to be an error, but,
+because it's hard to work around, Clang downgrades it to a warning as
+an extension.</p>
+</dd>
+
</dl>
<!-- ======================================================================= -->
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=105518&r1=105517&r2=105518&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jun 4 20:39:57 2010
@@ -20,6 +20,7 @@
def : DiagGroup<"address">;
def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
+def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
def : DiagGroup<"c++-compat">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=105518&r1=105517&r2=105518&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 4 20:39:57 2010
@@ -549,6 +549,9 @@
"parameter">;
def err_nested_name_member_ref_lookup_ambiguous : Error<
"lookup of %0 in member access expression is ambiguous">;
+def ext_nested_name_member_ref_lookup_ambiguous : ExtWarn<
+ "lookup of %0 in member access expression is ambiguous; using member of %1">,
+ InGroup<AmbigMemberTemplate>;
def note_ambig_member_ref_object_type : Note<
"lookup in the object type %0 refers here">;
def note_ambig_member_ref_scope : Note<
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=105518&r1=105517&r2=105518&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Jun 4 20:39:57 2010
@@ -311,8 +311,9 @@
Found.getFoundDecl()->getCanonicalDecl()
!= FoundOuter.getFoundDecl()->getCanonicalDecl()) {
Diag(Found.getNameLoc(),
- diag::err_nested_name_member_ref_lookup_ambiguous)
- << Found.getLookupName();
+ diag::ext_nested_name_member_ref_lookup_ambiguous)
+ << Found.getLookupName()
+ << ObjectType;
Diag(Found.getRepresentativeDecl()->getLocation(),
diag::note_ambig_member_ref_object_type)
<< ObjectType;
Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp?rev=105518&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp Fri Jun 4 20:39:57 2010
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s
+
+// C++98 [basic.lookup.classref]p1:
+// In a class member access expression (5.2.5), if the . or -> token is
+// immediately followed by an identifier followed by a <, the identifier must
+// be looked up to determine whether the < is the beginning of a template
+// argument list (14.2) or a less-than operator. The identifier is first
+// looked up in the class of the object expression. If the identifier is not
+// found, it is then looked up in the context of the entire postfix-expression
+// and shall name a class or function template. If the lookup in the class of
+// the object expression finds a template, the name is also looked up in the
+// context of the entire postfix-expression and
+// -- if the name is not found, the name found in the class of the object
+// expression is used, otherwise
+// -- if the name is found in the context of the entire postfix-expression
+// and does not name a class template, the name found in the class of the
+// object expression is used, otherwise
+// -- if the name found is a class template, it must refer to the same
+// entity as the one found in the class of the object expression,
+// otherwise the program is ill-formed.
+
+// From PR 7247
+template<typename T>
+struct set{}; // expected-note{{lookup from the current scope refers here}}
+struct Value {
+ template<typename T>
+ void set(T value) {} // expected-note{{lookup in the object type 'Value' refers here}}
+
+ void resolves_to_same() {
+ Value v;
+ v.set<double>(3.2);
+ }
+};
+void resolves_to_different() {
+ {
+ Value v;
+ // The fact that the next line is a warning rather than an error is an
+ // extension.
+ v.set<double>(3.2); // expected-warning{{lookup of 'set' in member access expression is ambiguous; using member of 'Value' [-Wambiguous-member-template]}}
+ }
+ {
+ int set; // Non-template.
+ Value v;
+ v.set<double>(3.2);
+ }
+}
More information about the cfe-commits
mailing list