r373866 - Implements CWG 1601 in [over.ics.rank/4.2]
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 6 11:50:40 PDT 2019
Author: rsmith
Date: Sun Oct 6 11:50:40 2019
New Revision: 373866
URL: http://llvm.org/viewvc/llvm-project?rev=373866&view=rev
Log:
Implements CWG 1601 in [over.ics.rank/4.2]
Summary:
The overload resolution for enums with a fixed underlying type has changed in the C++14 standard. This patch implements the new rule.
Patch by Mark de Wever!
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65695
Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/CXX/drs/dr16xx.cpp
cfe/trunk/test/CXX/drs/dr6xx.cpp
cfe/trunk/www/cxx_dr_status.html
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=373866&r1=373865&r2=373866&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Oct 6 11:50:40 2019
@@ -3765,6 +3765,34 @@ isBetterReferenceBindingKind(const Stand
!SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue);
}
+enum class FixedEnumPromotion {
+ None,
+ ToUnderlyingType,
+ ToPromotedUnderlyingType
+};
+
+/// Returns kind of fixed enum promotion the \a SCS uses.
+static FixedEnumPromotion
+getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) {
+
+ if (SCS.Second != ICK_Integral_Promotion)
+ return FixedEnumPromotion::None;
+
+ QualType FromType = SCS.getFromType();
+ if (!FromType->isEnumeralType())
+ return FixedEnumPromotion::None;
+
+ EnumDecl *Enum = FromType->getAs<EnumType>()->getDecl();
+ if (!Enum->isFixed())
+ return FixedEnumPromotion::None;
+
+ QualType UnderlyingType = Enum->getIntegerType();
+ if (S.Context.hasSameType(SCS.getToType(1), UnderlyingType))
+ return FixedEnumPromotion::ToUnderlyingType;
+
+ return FixedEnumPromotion::ToPromotedUnderlyingType;
+}
+
/// 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).
@@ -3806,6 +3834,20 @@ CompareStandardConversionSequences(Sema
? 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.
+ FixedEnumPromotion FEP1 = getFixedEnumPromtion(S, SCS1);
+ FixedEnumPromotion FEP2 = getFixedEnumPromtion(S, SCS2);
+ if (FEP1 != FixedEnumPromotion::None && FEP2 != FixedEnumPromotion::None &&
+ FEP1 != FEP2)
+ return FEP1 == FixedEnumPromotion::ToUnderlyingType
+ ? ImplicitConversionSequence::Better
+ : ImplicitConversionSequence::Worse;
+
// C++ [over.ics.rank]p4b2:
//
// If class B is derived directly or indirectly from class A,
Modified: cfe/trunk/test/CXX/drs/dr16xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr16xx.cpp?rev=373866&r1=373865&r2=373866&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr16xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr16xx.cpp Sun Oct 6 11:50:40 2019
@@ -23,6 +23,18 @@ namespace std {
} // std
#endif
+namespace dr1601 { // dr1601: 10
+enum E : char { e };
+#if __cplusplus < 201103L
+ // expected-error at -2 {{enumeration types with a fixed underlying type are a C++11 extension}}
+#endif
+void f(char);
+void f(int);
+void g() {
+ f(e);
+}
+} // namespace dr1601
+
namespace dr1611 { // dr1611: dup 1658
struct A { A(int); };
struct B : virtual A { virtual void f() = 0; };
Modified: cfe/trunk/test/CXX/drs/dr6xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr6xx.cpp?rev=373866&r1=373865&r2=373866&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr6xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr6xx.cpp Sun Oct 6 11:50:40 2019
@@ -987,14 +987,19 @@ namespace dr684 { // dr684: sup 1454
}
#endif
-#if __cplusplus >= 201103L
namespace dr685 { // dr685: yes
enum E : long { e };
+#if __cplusplus < 201103L
+ // expected-error at -2 {{enumeration types with a fixed underlying type are a C++11 extension}}
+#endif
void f(int);
int f(long);
int a = f(e);
enum G : short { g };
+#if __cplusplus < 201103L
+ // expected-error at -2 {{enumeration types with a fixed underlying type are a C++11 extension}}
+#endif
int h(short);
void h(long);
int b = h(g);
@@ -1007,11 +1012,11 @@ namespace dr685 { // dr685: yes
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
namespace dr686 { // dr686: yes
void f() {
Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=373866&r1=373865&r2=373866&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Sun Oct 6 11:50:40 2019
@@ -9421,7 +9421,7 @@ and <I>POD class</I></td>
<td><a href="http://wg21.link/cwg1601">1601</a></td>
<td>C++14</td>
<td>Promotion of enumeration with fixed underlying type</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr class="open" id="1602">
<td><a href="http://wg21.link/cwg1602">1602</a></td>
More information about the cfe-commits
mailing list