diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index 19c9f8337072..bed79de1b6a1 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -272,6 +272,7 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 336166dd7234..c5b8a71f4439 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -929,6 +929,10 @@ public: /// an objective pointer type for the purpose of GC'ability bool hasObjCPointerRepresentation() const; + /// \brief Determine whether this type has a floating-point representation + /// of some sort, e.g., it is a floating-point type or a vector thereof. + bool hasFloatingRepresentation() const; + // Type Checking Functions: Check to see if this type is structurally the // specified type, ignoring typedefs and qualifiers, and return a pointer to // the best type we can. diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index a1d12a38cad9..11fd42d62acb 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -563,9 +563,14 @@ bool Type::isFloatingType() const { BT->getKind() <= BuiltinType::LongDouble; if (const ComplexType *CT = dyn_cast(CanonicalType)) return CT->getElementType()->isFloatingType(); + return false; +} + +bool Type::hasFloatingRepresentation() const { if (const VectorType *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isFloatingType(); - return false; + else + return isFloatingType(); } bool Type::isRealFloatingType() const { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index dee10fb608a1..527b469fed8f 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1410,7 +1410,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, FieldDecl *FirstField = *Field; QualType FirstType = FirstField->getType(); - if (FirstType->isFloatingType() || FirstType->isVectorType()) { + if (FirstType->hasFloatingRepresentation()) { S.Diag(FirstField->getLocation(), diag::warn_transparent_union_attribute_floating); return; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5e7a733e0fdf..eb66d9d6c01a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5267,8 +5267,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, QualType lType = lex->getType(); QualType rType = rex->getType(); - if (!lType->isFloatingType() - && !(lType->isBlockPointerType() && isRelational)) { + if (!lType->hasFloatingRepresentation() && + !(lType->isBlockPointerType() && isRelational)) { // For non-floating point types, check for self-comparisons of the form // x == x, x != x, x < x, etc. These always evaluate to a constant, and // often indicate logic errors in the program. @@ -5368,7 +5368,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, return ResultTy; } else { // Check for comparisons of floating point operands using != and ==. - if (lType->isFloatingType() && rType->isFloatingType()) + if (lType->hasFloatingRepresentation()) CheckFloatComparison(Loc,lex,rex); if (lType->isArithmeticType() && rType->isArithmeticType()) @@ -5634,7 +5634,7 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, // For non-floating point types, check for self-comparisons of the form // x == x, x != x, x < x, etc. These always evaluate to a constant, and // often indicate logic errors in the program. - if (!lType->isFloatingType()) { + if (!lType->hasFloatingRepresentation()) { if (DeclRefExpr* DRL = dyn_cast(lex->IgnoreParens())) if (DeclRefExpr* DRR = dyn_cast(rex->IgnoreParens())) if (DRL->getDecl() == DRR->getDecl()) @@ -5646,8 +5646,8 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, } // Check for comparisons of floating point operands using != and ==. - if (!isRelational && lType->isFloatingType()) { - assert (rType->isFloatingType()); + if (!isRelational && lType->hasFloatingRepresentation()) { + assert (rType->hasFloatingRepresentation()); CheckFloatComparison(Loc,lex,rex); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a22556a7e5a9..b4133e8b4ac7 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1015,18 +1015,14 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, // Complex-real conversions (C99 6.3.1.7) SCS.Second = ICK_Complex_Real; FromType = ToType.getUnqualifiedType(); - } else if (FromType->isFloatingType() && ToType->isFloatingType() && - /*FIXME*/!FromType->isVectorType() && - /*FIXME*/!ToType->isVectorType()) { + } else if (FromType->isFloatingType() && ToType->isFloatingType()) { // Floating point conversions (C++ 4.8). SCS.Second = ICK_Floating_Conversion; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isFloatingType() && - /*FIXME*/!FromType->isVectorType() && ToType->isIntegralType(Context) && !ToType->isBooleanType()) || (FromType->isIntegralOrEnumerationType() && - ToType->isFloatingType() && - /*FIXME*/!FromType->isVectorType())) { + ToType->isFloatingType())) { // Floating-integral conversions (C++ 4.9). SCS.Second = ICK_Floating_Integral; FromType = ToType.getUnqualifiedType();