Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -7615,53 +7615,58 @@ SmallVectorImpl &CandidateTypes; OverloadCandidateSet &CandidateSet; - // Define some constants used to index and iterate over the arithemetic types - // provided via the getArithmeticType() method below. - // The "promoted arithmetic types" are the arithmetic + SmallVector ArithmeticTypes; + + // Define some indices used to iterate over the arithemetic types in + // ArithmeticTypes. The "promoted arithmetic types" are the arithmetic // types are that preserved by promotion (C++ [over.built]p2). - static const unsigned FirstIntegralType = 4; - static const unsigned LastIntegralType = 21; - static const unsigned FirstPromotedIntegralType = 4, - LastPromotedIntegralType = 12; - static const unsigned FirstPromotedArithmeticType = 0, - LastPromotedArithmeticType = 12; - static const unsigned NumArithmeticTypes = 21; - - /// \brief Get the canonical type for a given arithmetic type index. - CanQualType getArithmeticType(unsigned index) { - assert(index < NumArithmeticTypes); - static CanQualType ASTContext::* const - ArithmeticTypes[NumArithmeticTypes] = { - // Start of promoted types. - &ASTContext::FloatTy, - &ASTContext::DoubleTy, - &ASTContext::LongDoubleTy, - &ASTContext::Float128Ty, - - // Start of integral types. - &ASTContext::IntTy, - &ASTContext::LongTy, - &ASTContext::LongLongTy, - &ASTContext::Int128Ty, - &ASTContext::UnsignedIntTy, - &ASTContext::UnsignedLongTy, - &ASTContext::UnsignedLongLongTy, - &ASTContext::UnsignedInt128Ty, - // End of promoted types. - - &ASTContext::BoolTy, - &ASTContext::CharTy, - &ASTContext::WCharTy, - &ASTContext::Char16Ty, - &ASTContext::Char32Ty, - &ASTContext::SignedCharTy, - &ASTContext::ShortTy, - &ASTContext::UnsignedCharTy, - &ASTContext::UnsignedShortTy, - // End of integral types. - // FIXME: What about complex? What about half? - }; - return S.Context.*ArithmeticTypes[index]; + unsigned FirstIntegralType, + LastIntegralType; + unsigned FirstPromotedIntegralType, + LastPromotedIntegralType; + unsigned FirstPromotedArithmeticType, + LastPromotedArithmeticType; + unsigned NumArithmeticTypes; + + void InitArithmeticTypes() { + // Start of promoted types. + FirstPromotedArithmeticType = 0; + ArithmeticTypes.push_back(S.Context.FloatTy); + ArithmeticTypes.push_back(S.Context.DoubleTy); + ArithmeticTypes.push_back(S.Context.LongDoubleTy); + if (S.Context.getTargetInfo().hasFloat128Type()) + ArithmeticTypes.push_back(S.Context.Float128Ty); + + // Start of integral types. + FirstIntegralType = ArithmeticTypes.size(); + FirstPromotedIntegralType = ArithmeticTypes.size(); + ArithmeticTypes.push_back(S.Context.IntTy); + ArithmeticTypes.push_back(S.Context.LongTy); + ArithmeticTypes.push_back(S.Context.LongLongTy); + if (S.Context.getTargetInfo().hasInt128Type()) + ArithmeticTypes.push_back(S.Context.Int128Ty); + ArithmeticTypes.push_back(S.Context.UnsignedIntTy); + ArithmeticTypes.push_back(S.Context.UnsignedLongTy); + ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy); + if (S.Context.getTargetInfo().hasInt128Type()) + ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty); + LastPromotedIntegralType = ArithmeticTypes.size(); + LastPromotedArithmeticType = ArithmeticTypes.size(); + // End of promoted types. + + ArithmeticTypes.push_back(S.Context.BoolTy); + ArithmeticTypes.push_back(S.Context.CharTy); + ArithmeticTypes.push_back(S.Context.WCharTy); + ArithmeticTypes.push_back(S.Context.Char16Ty); + ArithmeticTypes.push_back(S.Context.Char32Ty); + ArithmeticTypes.push_back(S.Context.SignedCharTy); + ArithmeticTypes.push_back(S.Context.ShortTy); + ArithmeticTypes.push_back(S.Context.UnsignedCharTy); + ArithmeticTypes.push_back(S.Context.UnsignedShortTy); + LastIntegralType = ArithmeticTypes.size(); + NumArithmeticTypes = ArithmeticTypes.size(); + // End of integral types. + // FIXME: What about complex? What about half?/ } /// \brief Helper method to factor out the common pattern of adding overloads @@ -7720,17 +7725,24 @@ HasArithmeticOrEnumeralCandidateType), CandidateTypes(CandidateTypes), CandidateSet(CandidateSet) { + + InitArithmeticTypes(); + // Validate some of our static helper constants in debug builds. - assert(getArithmeticType(FirstPromotedIntegralType) == S.Context.IntTy && + assert(ArithmeticTypes[FirstPromotedIntegralType] == S.Context.IntTy && "Invalid first promoted integral type"); - assert(getArithmeticType(LastPromotedIntegralType - 1) - == S.Context.UnsignedInt128Ty && + assert((ArithmeticTypes[LastPromotedIntegralType - 1] == + S.Context.UnsignedInt128Ty || + ArithmeticTypes[LastPromotedIntegralType - 1] == + S.Context.UnsignedLongLongTy) && "Invalid last promoted integral type"); - assert(getArithmeticType(FirstPromotedArithmeticType) + assert(ArithmeticTypes[FirstPromotedArithmeticType] == S.Context.FloatTy && "Invalid first promoted arithmetic type"); - assert(getArithmeticType(LastPromotedArithmeticType - 1) - == S.Context.UnsignedInt128Ty && + assert((ArithmeticTypes[LastPromotedArithmeticType - 1] == + S.Context.UnsignedInt128Ty || + ArithmeticTypes[LastPromotedArithmeticType - 1] == + S.Context.UnsignedLongLongTy) && "Invalid last promoted arithmetic type"); } @@ -7758,7 +7770,7 @@ for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1); Arith < NumArithmeticTypes; ++Arith) { addPlusPlusMinusMinusStyleOverloads( - getArithmeticType(Arith), + ArithmeticTypes[Arith], VisibleTypeConversionsQuals.hasVolatile(), VisibleTypeConversionsQuals.hasRestrict()); } @@ -7831,7 +7843,7 @@ for (unsigned Arith = FirstPromotedArithmeticType; Arith < LastPromotedArithmeticType; ++Arith) { - QualType ArithTy = getArithmeticType(Arith); + QualType ArithTy = ArithmeticTypes[Arith]; S.AddBuiltinCandidate(&ArithTy, Args, CandidateSet); } @@ -7871,7 +7883,7 @@ for (unsigned Int = FirstPromotedIntegralType; Int < LastPromotedIntegralType; ++Int) { - QualType IntTy = getArithmeticType(Int); + QualType IntTy = ArithmeticTypes[Int]; S.AddBuiltinCandidate(&IntTy, Args, CandidateSet); } @@ -8099,8 +8111,8 @@ Left < LastPromotedArithmeticType; ++Left) { for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { - QualType LandR[2] = { getArithmeticType(Left), - getArithmeticType(Right) }; + QualType LandR[2] = { ArithmeticTypes[Left], + ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } @@ -8143,8 +8155,8 @@ Left < LastPromotedIntegralType; ++Left) { for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { - QualType LandR[2] = { getArithmeticType(Left), - getArithmeticType(Right) }; + QualType LandR[2] = { ArithmeticTypes[Left], + ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } @@ -8324,18 +8336,18 @@ for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { QualType ParamTypes[2]; - ParamTypes[1] = getArithmeticType(Right); + ParamTypes[1] = ArithmeticTypes[Right]; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = - S.Context.getLValueReferenceType(getArithmeticType(Left)); + S.Context.getLValueReferenceType(ArithmeticTypes[Left]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = - S.Context.getVolatileType(getArithmeticType(Left)); + S.Context.getVolatileType(ArithmeticTypes[Left]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); @@ -8390,15 +8402,15 @@ for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { QualType ParamTypes[2]; - ParamTypes[1] = getArithmeticType(Right); + ParamTypes[1] = ArithmeticTypes[Right]; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = - S.Context.getLValueReferenceType(getArithmeticType(Left)); + S.Context.getLValueReferenceType(ArithmeticTypes[Left]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). - ParamTypes[0] = getArithmeticType(Left); + ParamTypes[0] = ArithmeticTypes[Left]; ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); Index: test/CodeGenCXX/microsoft-cannot-mangle-float128.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/microsoft-cannot-mangle-float128.cpp @@ -0,0 +1,14 @@ +// RUN: not %clang_cc1 -triple i686-pc-win32 %s -std=c++17 -emit-obj 2>&1 | FileCheck %s + +template struct B; +template constexpr bool is_floating_point_v = false; + +struct StrictNumeric { + StrictNumeric(int); + template > = nullptr> operator Dst(); +}; + +static_assert(StrictNumeric(1) > 0); + +// CHECK-NOT: cannot mangle this built-in __float128 type +// CHECK: invalid operands to binary expression