[PATCH] D65695: Implements CWG 1601 in [over.ics.rank/4.2]
Mark de Wever via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 15 12:49:01 PDT 2019
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,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65695.215457.patch
Type: text/x-patch
Size: 3130 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190815/df800735/attachment-0001.bin>
More information about the cfe-commits
mailing list