Mordante updated this revision to Diff 215457.
Mordante added a comment.

Add the proper markers in the unit test to update `cxx_dr_status.html`. As 
discussed on IRC; the up to date `cwg_index.html` is not public, so I only 
updated the unit test and removed the changes to `cxx_dr_status.html`.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65695/new/

https://reviews.llvm.org/D65695

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/drs/dr16xx.cpp
  clang/test/CXX/drs/dr6xx.cpp


Index: clang/test/CXX/drs/dr6xx.cpp
===================================================================
--- clang/test/CXX/drs/dr6xx.cpp
+++ clang/test/CXX/drs/dr6xx.cpp
@@ -1007,9 +1007,10 @@
   void j(long); // expected-note {{candidate}}
   int d = j(g); // expected-error {{ambiguous}}
 
-  int k(short); // expected-note {{candidate}}
-  void k(int); // expected-note {{candidate}}
-  int x = k(g); // expected-error {{ambiguous}}
+  // Valid per dr1601
+  int k(short);
+  void k(int);
+  int x = k(g);
 }
 #endif
 
Index: clang/test/CXX/drs/dr16xx.cpp
===================================================================
--- clang/test/CXX/drs/dr16xx.cpp
+++ clang/test/CXX/drs/dr16xx.cpp
@@ -23,6 +23,17 @@
 } // std
 #endif
 
+namespace dr1601 { // dr1601: 10 c++11
+#if __cplusplus >= 201103L
+enum E : char { e };
+void f(char);
+void f(int);
+void g() {
+  f(e);
+}
+#endif
+} // namespace dr1601
+
 namespace dr1611 { // dr1611: dup 1658
   struct A { A(int); };
   struct B : virtual A { virtual void f() = 0; };
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -3751,6 +3751,26 @@
           !SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue);
 }
 
+/// Returns the underlaying type of a fixed enum of the \a SCS's \c FromType
+/// if the \a SCS uses an integral promotion. Upon failure an empty type is
+/// returned.
+static QualType
+getFixedEnumUnderlayingType(const StandardConversionSequence &SCS) {
+
+  if (SCS.Second != ICK_Integral_Promotion)
+    return QualType();
+
+  QualType FromType = SCS.getFromType();
+  if (!FromType->isEnumeralType())
+    return QualType();
+
+  EnumDecl *Enum = FromType->getAs<EnumType>()->getDecl();
+  if (!Enum->isFixed())
+    return QualType();
+
+  return Enum->getIntegerType();
+}
+
 /// CompareStandardConversionSequences - Compare two standard
 /// conversion sequences to determine whether one is better than the
 /// other or if they are indistinguishable (C++ 13.3.3.2p3).
@@ -3792,6 +3812,23 @@
              ? ImplicitConversionSequence::Better
              : ImplicitConversionSequence::Worse;
 
+  // C++14 [over.ics.rank]p4b2:
+  // This is retroactively applied to C++11 by CWG 1601.
+  //
+  //   A conversion that promotes an enumeration whose underlying type is fixed
+  //   to its underlying type is better than one that promotes to the promoted
+  //   underlying type, if the two are different.
+  QualType UnderlayingType1 = getFixedEnumUnderlayingType(SCS1);
+  QualType UnderlayingType2 = getFixedEnumUnderlayingType(SCS2);
+  if (!UnderlayingType1.isNull() && !UnderlayingType2.isNull()) {
+    if (SCS1.getToType(1) == UnderlayingType1 &&
+        SCS2.getToType(1) != UnderlayingType2)
+      return ImplicitConversionSequence::Better;
+    else if (SCS1.getToType(1) != UnderlayingType1 &&
+             SCS2.getToType(1) == UnderlayingType2)
+      return ImplicitConversionSequence::Worse;
+  }
+
   // C++ [over.ics.rank]p4b2:
   //
   //   If class B is derived directly or indirectly from class A,


Index: clang/test/CXX/drs/dr6xx.cpp
===================================================================
--- clang/test/CXX/drs/dr6xx.cpp
+++ clang/test/CXX/drs/dr6xx.cpp
@@ -1007,9 +1007,10 @@
   void j(long); // expected-note {{candidate}}
   int d = j(g); // expected-error {{ambiguous}}
 
-  int k(short); // expected-note {{candidate}}
-  void k(int); // expected-note {{candidate}}
-  int x = k(g); // expected-error {{ambiguous}}
+  // Valid per dr1601
+  int k(short);
+  void k(int);
+  int x = k(g);
 }
 #endif
 
Index: clang/test/CXX/drs/dr16xx.cpp
===================================================================
--- clang/test/CXX/drs/dr16xx.cpp
+++ clang/test/CXX/drs/dr16xx.cpp
@@ -23,6 +23,17 @@
 } // std
 #endif
 
+namespace dr1601 { // dr1601: 10 c++11
+#if __cplusplus >= 201103L
+enum E : char { e };
+void f(char);
+void f(int);
+void g() {
+  f(e);
+}
+#endif
+} // namespace dr1601
+
 namespace dr1611 { // dr1611: dup 1658
   struct A { A(int); };
   struct B : virtual A { virtual void f() = 0; };
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -3751,6 +3751,26 @@
           !SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue);
 }
 
+/// Returns the underlaying type of a fixed enum of the \a SCS's \c FromType
+/// if the \a SCS uses an integral promotion. Upon failure an empty type is
+/// returned.
+static QualType
+getFixedEnumUnderlayingType(const StandardConversionSequence &SCS) {
+
+  if (SCS.Second != ICK_Integral_Promotion)
+    return QualType();
+
+  QualType FromType = SCS.getFromType();
+  if (!FromType->isEnumeralType())
+    return QualType();
+
+  EnumDecl *Enum = FromType->getAs<EnumType>()->getDecl();
+  if (!Enum->isFixed())
+    return QualType();
+
+  return Enum->getIntegerType();
+}
+
 /// CompareStandardConversionSequences - Compare two standard
 /// conversion sequences to determine whether one is better than the
 /// other or if they are indistinguishable (C++ 13.3.3.2p3).
@@ -3792,6 +3812,23 @@
              ? ImplicitConversionSequence::Better
              : ImplicitConversionSequence::Worse;
 
+  // C++14 [over.ics.rank]p4b2:
+  // This is retroactively applied to C++11 by CWG 1601.
+  //
+  //   A conversion that promotes an enumeration whose underlying type is fixed
+  //   to its underlying type is better than one that promotes to the promoted
+  //   underlying type, if the two are different.
+  QualType UnderlayingType1 = getFixedEnumUnderlayingType(SCS1);
+  QualType UnderlayingType2 = getFixedEnumUnderlayingType(SCS2);
+  if (!UnderlayingType1.isNull() && !UnderlayingType2.isNull()) {
+    if (SCS1.getToType(1) == UnderlayingType1 &&
+        SCS2.getToType(1) != UnderlayingType2)
+      return ImplicitConversionSequence::Better;
+    else if (SCS1.getToType(1) != UnderlayingType1 &&
+             SCS2.getToType(1) == UnderlayingType2)
+      return ImplicitConversionSequence::Worse;
+  }
+
   // C++ [over.ics.rank]p4b2:
   //
   //   If class B is derived directly or indirectly from class A,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to