From 0b8ddb9a4743465cd76e9f134a2f55ab2330a0a4 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 21 Oct 2010 18:04:08 +0000 Subject: [PATCH] Implement the integral promotion rules for the C++0x char16_t and char32_t character types and enable built-in overloaded operator candidates for these types. Fixes PR8432. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117038 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOverload.cpp | 45 +++++++++++++------ .../overloaded-builtin-operators-0x.cpp | 11 +++++ 2 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 test/SemaCXX/overloaded-builtin-operators-0x.cpp diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index d2f6ee725d..8f653d1df0 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1187,25 +1187,42 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { return To->getKind() == BuiltinType::UInt; } - // An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) - // can be converted to an rvalue of the first of the following types - // that can represent all the values of its underlying type: int, - // unsigned int, long, or unsigned long (C++ 4.5p2). - - // We pre-calculate the promotion type for enum types. + // C++0x [conv.prom]p3: + // A prvalue of an unscoped enumeration type whose underlying type is not + // fixed (7.2) can be converted to an rvalue a prvalue of the first of the + // following types that can represent all the values of the enumeration + // (i.e., the values in the range bmin to bmax as described in 7.2): int, + // unsigned int, long int, unsigned long int, long long int, or unsigned + // long long int. If none of the types in that list can represent all the + // values of the enumeration, an rvalue a prvalue of an unscoped enumeration + // type can be converted to an rvalue a prvalue of the extended integer type + // with lowest integer conversion rank (4.13) greater than the rank of long + // long in which all the values of the enumeration can be represented. If + // there are two such extended types, the signed one is chosen. if (const EnumType *FromEnumType = FromType->getAs()) { // C++0x 7.2p9: Note that this implicit enum to int conversion is not // provided for a scoped enumeration. if (FromEnumType->getDecl()->isScoped()) return false; + // We have already pre-calculated the promotion type, so this is trivial. if (ToType->isIntegerType() && !RequireCompleteType(From->getLocStart(), FromType, PDiag())) return Context.hasSameUnqualifiedType(ToType, FromEnumType->getDecl()->getPromotionType()); } - if (FromType->isWideCharType() && ToType->isIntegerType()) { + // C++0x [conv.prom]p2: + // A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted + // to an rvalue a prvalue of the first of the following types that can + // represent all the values of its underlying type: int, unsigned int, + // long int, unsigned long int, long long int, or unsigned long long int. + // If none of the types in that list can represent all the values of its + // underlying type, an rvalue a prvalue of type char16_t, char32_t, + // or wchar_t can be converted to an rvalue a prvalue of its underlying + // type. + if (FromType->isAnyCharacterType() && !FromType->isCharType() && + ToType->isIntegerType()) { // Determine whether the type we're converting from is signed or // unsigned. bool FromIsSigned; @@ -4490,15 +4507,15 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, // types; these types need to be first. // FIXME: What about complex? const unsigned FirstIntegralType = 0; - const unsigned LastIntegralType = 13; - const unsigned FirstPromotedIntegralType = 7, - LastPromotedIntegralType = 13; - const unsigned FirstPromotedArithmeticType = 7, - LastPromotedArithmeticType = 16; - const unsigned NumArithmeticTypes = 16; + const unsigned LastIntegralType = 15; + const unsigned FirstPromotedIntegralType = 9, + LastPromotedIntegralType = 15; + const unsigned FirstPromotedArithmeticType = 9, + LastPromotedArithmeticType = 18; + const unsigned NumArithmeticTypes = 18; QualType ArithmeticTypes[NumArithmeticTypes] = { Context.BoolTy, Context.CharTy, Context.WCharTy, -// FIXME: Context.Char16Ty, Context.Char32Ty, + Context.Char16Ty, Context.Char32Ty, Context.SignedCharTy, Context.ShortTy, Context.UnsignedCharTy, Context.UnsignedShortTy, Context.IntTy, Context.LongTy, Context.LongLongTy, diff --git a/test/SemaCXX/overloaded-builtin-operators-0x.cpp b/test/SemaCXX/overloaded-builtin-operators-0x.cpp new file mode 100644 index 0000000000..32f1995290 --- /dev/null +++ b/test/SemaCXX/overloaded-builtin-operators-0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -std=c++0x -verify %s + +template +struct X +{ + operator T() const {return T();} +}; + +void test_char16t(X x) { + bool b = x == char16_t(); +} -- 2.40.0