r264363 - Fix nondeterminism in computation of builtin operator overload sets.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 24 17:08:53 PDT 2016


Author: rsmith
Date: Thu Mar 24 19:08:53 2016
New Revision: 264363

URL: http://llvm.org/viewvc/llvm-project?rev=264363&view=rev
Log:
Fix nondeterminism in computation of builtin operator overload sets.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/diagnostic-order.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=264363&r1=264362&r2=264363&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Mar 24 19:08:53 2016
@@ -6818,7 +6818,8 @@ namespace {
 /// enumeration types.
 class BuiltinCandidateTypeSet  {
   /// TypeSet - A set of types.
-  typedef llvm::SmallPtrSet<QualType, 8> TypeSet;
+  typedef llvm::SetVector<QualType, SmallVector<QualType, 8>,
+                          llvm::SmallPtrSet<QualType, 8>> TypeSet;
 
   /// PointerTypes - The set of pointer types that will be used in the
   /// built-in candidates.
@@ -6917,7 +6918,7 @@ BuiltinCandidateTypeSet::AddPointerWithM
                                              const Qualifiers &VisibleQuals) {
 
   // Insert this type.
-  if (!PointerTypes.insert(Ty).second)
+  if (!PointerTypes.insert(Ty))
     return false;
 
   QualType PointeeTy;
@@ -6985,7 +6986,7 @@ bool
 BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
     QualType Ty) {
   // Insert this type.
-  if (!MemberPointerTypes.insert(Ty).second)
+  if (!MemberPointerTypes.insert(Ty))
     return false;
 
   const MemberPointerType *PointerTy = Ty->getAs<MemberPointerType>();

Modified: cfe/trunk/test/SemaCXX/diagnostic-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/diagnostic-order.cpp?rev=264363&r1=264362&r2=264363&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/diagnostic-order.cpp (original)
+++ cfe/trunk/test/SemaCXX/diagnostic-order.cpp Thu Mar 24 19:08:53 2016
@@ -3,9 +3,9 @@
 // Ensure that the diagnostics we produce for this situation appear in a
 // deterministic order. This requires ADL to provide lookup results in a
 // deterministic order.
-template<typename T> struct Error { typedef typename T::error error; };
-struct X { template<typename T> friend typename Error<T>::error f(X, T); };
-struct Y { template<typename T> friend typename Error<T>::error f(T, Y); };
+template<typename T, typename> struct Error { typedef typename T::error error; };
+struct X { template<typename T> friend typename Error<X, T>::error f(X, T); };
+struct Y { template<typename T> friend typename Error<Y, T>::error f(T, Y); };
 
 void g() {
   f(X(), Y());
@@ -15,6 +15,43 @@ void g() {
 // order below is source order, which seems best). The crucial fact is that
 // there is one single order that is stable across multiple runs of clang.
 //
-// CHECK: no type named 'error' in 'Y'
 // CHECK: no type named 'error' in 'X'
+// CHECK: no type named 'error' in 'Y'
 // CHECK: no matching function for call to 'f'
+
+
+struct Oper {
+  template<typename T, typename U = typename Error<Oper, T>::error> operator T();
+
+  operator int*();
+  operator float*();
+  operator X*();
+  operator Y*();
+
+  operator int(*[1])();
+  operator int(*[2])();
+  operator int(*[3])();
+  operator int(*[4])();
+  operator int(*[5])();
+  operator int(*[6])();
+  operator int(*[7])();
+  operator int(*[8])();
+  operator float(*[1])();
+  operator float(*[2])();
+  operator float(*[3])();
+  operator float(*[4])();
+  operator float(*[5])();
+  operator float(*[6])();
+  operator float(*[7])();
+  operator float(*[8])();
+};
+int *p = Oper() + 0;
+
+// CHECK: no type named 'error' in 'Oper'
+// CHECK: in instantiation of template class 'Error<Oper, int *>'
+// CHECK: no type named 'error' in 'Oper'
+// CHECK: in instantiation of template class 'Error<Oper, float *>'
+// CHECK: no type named 'error' in 'Oper'
+// CHECK: in instantiation of template class 'Error<Oper, X *>'
+// CHECK: no type named 'error' in 'Oper'
+// CHECK: in instantiation of template class 'Error<Oper, Y *>'




More information about the cfe-commits mailing list