[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