зеркало из https://github.com/microsoft/clang.git
Implement C++0x [expr.static.cast]p9, which permits explicitly casting
a scoped enumeration type to an integral or floating type, properly. There was an over-eager assertion, and it was missing the floating-point case. Fixes PR9107/<rdar://problem/8937402>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125825 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
0d3c985ad5
Коммит
1e856d99c5
|
@ -688,18 +688,23 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
|
|||
QualType SrcType = Self.Context.getCanonicalType(SrcExpr->getType());
|
||||
|
||||
// C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly
|
||||
// converted to an integral type.
|
||||
if (Self.getLangOptions().CPlusPlus0x && SrcType->isEnumeralType()) {
|
||||
assert(SrcType->getAs<EnumType>()->getDecl()->isScoped());
|
||||
if (DestType->isBooleanType()) {
|
||||
Kind = CK_IntegralToBoolean;
|
||||
return TC_Success;
|
||||
} else if (DestType->isIntegralType(Self.Context)) {
|
||||
Kind = CK_IntegralCast;
|
||||
return TC_Success;
|
||||
// converted to an integral type. [...] A value of a scoped enumeration type
|
||||
// can also be explicitly converted to a floating-point type [...].
|
||||
if (const EnumType *Enum = SrcType->getAs<EnumType>()) {
|
||||
if (Enum->getDecl()->isScoped()) {
|
||||
if (DestType->isBooleanType()) {
|
||||
Kind = CK_IntegralToBoolean;
|
||||
return TC_Success;
|
||||
} else if (DestType->isIntegralType(Self.Context)) {
|
||||
Kind = CK_IntegralCast;
|
||||
return TC_Success;
|
||||
} else if (DestType->isRealFloatingType()) {
|
||||
Kind = CK_IntegralToFloating;
|
||||
return TC_Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reverse integral promotion/conversion. All such conversions are themselves
|
||||
// again integral promotions or conversions and are thus already handled by
|
||||
// p2 (TryDirectInitialization above).
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
|
||||
|
||||
enum class EC { ec1 };
|
||||
|
||||
void test0(EC ec) {
|
||||
(void)static_cast<bool>(ec);
|
||||
(void)static_cast<bool>(EC::ec1);
|
||||
(void)static_cast<char>(ec);
|
||||
(void)static_cast<char>(EC::ec1);
|
||||
(void)static_cast<int>(ec);
|
||||
(void)static_cast<int>(EC::ec1);
|
||||
(void)static_cast<unsigned long>(ec);
|
||||
(void)static_cast<unsigned long>(EC::ec1);
|
||||
(void)static_cast<float>(ec);
|
||||
(void)static_cast<float>(EC::ec1);
|
||||
(void)static_cast<double>(ec);
|
||||
(void)static_cast<double>(EC::ec1);
|
||||
}
|
||||
|
||||
namespace PR9107 {
|
||||
enum E {};
|
||||
template <class _Tp> inline _Tp* addressof(_Tp& __x) {
|
||||
return (_Tp*)&(char&)__x;
|
||||
}
|
||||
void test() {
|
||||
E a;
|
||||
addressof(a);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче