llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Michele Scandale (michele-scandale) <details> <summary>Changes</summary> This is a follow-up of 13aac46332f607a38067b5ddd466071683b8c255. This commit adjusts the implementation of `hasBooleanRepresentation` to have a similar behavior as the one of `hasIntegerRepresentation`. In particular vector of booleans should be handled in `hasBooleanRepresentation`, while `_Atomic(bool)` should not. --- Full diff: https://github.com/llvm/llvm-project/pull/136038.diff 5 Files Affected: - (modified) clang/include/clang/AST/Decl.h (+8) - (modified) clang/include/clang/AST/Type.h (+9-1) - (modified) clang/lib/AST/Type.cpp (+3-10) - (modified) clang/lib/CodeGen/CGExpr.cpp (+13-7) - (modified) clang/lib/Sema/SemaType.cpp (+1-1) ``````````diff diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 3faf63e395a08..07ada202075a2 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -5238,6 +5238,14 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) { return ED->isScoped(); } +/// Return the integer type corresponding to the given decl. +/// +/// We use this function to break a cycle between the inline definitions in +/// Type.h and Decl.h. +inline QualType GetEnumDeclIntegerType(EnumDecl *ED) { + return ED->getIntegerType(); +} + /// OpenMP variants are mangled early based on their OpenMP context selector. /// The new name looks likes this: /// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context> diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 5bf036e3347eb..ce6904abcc71a 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2774,7 +2774,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool hasFloatingRepresentation() const; /// Determine whether this type has a boolean representation - /// of some sort. + /// of some sort, e.g., it is a boolean type or a vector thereof. bool hasBooleanRepresentation() const; // Type Checking Functions: Check to see if this type is structurally the @@ -8531,6 +8531,7 @@ inline bool Type::isNullPtrType() const { bool IsEnumDeclComplete(EnumDecl *); bool IsEnumDeclScoped(EnumDecl *); +QualType GetEnumDeclIntegerType(EnumDecl *); inline bool Type::isIntegerType() const { if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) @@ -8623,6 +8624,13 @@ inline bool Type::isIntegralOrEnumerationType() const { inline bool Type::isBooleanType() const { if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() == BuiltinType::Bool; + if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { + // Incomplete enum types are not treated as integer types. + // FIXME: In C++, enum types are never integer types. + return IsEnumDeclComplete(ET->getDecl()) && + !IsEnumDeclScoped(ET->getDecl()) && + GetEnumDeclIntegerType(ET->getDecl())->isBooleanType(); + } return false; } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 53620003c9655..b456f43d39224 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2336,16 +2336,9 @@ bool Type::isArithmeticType() const { } bool Type::hasBooleanRepresentation() const { - if (isBooleanType()) - return true; - - if (const EnumType *ET = getAs<EnumType>()) - return ET->getDecl()->getIntegerType()->isBooleanType(); - - if (const AtomicType *AT = getAs<AtomicType>()) - return AT->getValueType()->hasBooleanRepresentation(); - - return false; + if (const auto *VT = dyn_cast<VectorType>(CanonicalType)) + return VT->getElementType()->isBooleanType(); + return isBooleanType(); } Type::ScalarTypeKind Type::getScalarTypeKind() const { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index abb88477062fc..786a56eed7ed5 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1920,7 +1920,7 @@ static bool getRangeForType(CodeGenFunction &CGF, QualType Ty, llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { llvm::APInt Min, End; if (!getRangeForType(*this, Ty, Min, End, CGM.getCodeGenOpts().StrictEnums, - Ty->hasBooleanRepresentation())) + Ty->hasBooleanRepresentation() && !Ty->isVectorType())) return nullptr; llvm::MDBuilder MDHelper(getLLVMContext()); @@ -1948,7 +1948,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, if (!HasBoolCheck && !HasEnumCheck) return false; - bool IsBool = Ty->hasBooleanRepresentation() || + bool IsBool = (Ty->hasBooleanRepresentation() && !Ty->isVectorType()) || NSAPI(CGM.getContext()).isObjCBOOLType(Ty); bool NeedsBoolCheck = HasBoolCheck && IsBool; bool NeedsEnumCheck = HasEnumCheck && Ty->getAs<EnumType>(); @@ -2068,11 +2068,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, /// by ConvertType) to its load/store type (as returned by /// convertTypeForLoadStore). llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) { - if (Ty->hasBooleanRepresentation() || Ty->isBitIntType()) { - llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType()); - bool Signed = Ty->isSignedIntegerOrEnumerationType(); - return Builder.CreateIntCast(Value, StoreTy, Signed, "storedv"); - } + if (auto *AtomicTy = Ty->getAs<AtomicType>()) + Ty = AtomicTy->getValueType(); if (Ty->isExtVectorBoolType()) { llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType()); @@ -2088,6 +2085,12 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) { Value = Builder.CreateBitCast(Value, StoreTy); } + if (Ty->hasBooleanRepresentation() || Ty->isBitIntType()) { + llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType()); + bool Signed = Ty->isSignedIntegerOrEnumerationType(); + return Builder.CreateIntCast(Value, StoreTy, Signed, "storedv"); + } + return Value; } @@ -2095,6 +2098,9 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) { /// by convertTypeForLoadStore) to its primary IR type (as returned /// by ConvertType). llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) { + if (auto *AtomicTy = Ty->getAs<AtomicType>()) + Ty = AtomicTy->getValueType(); + if (Ty->isPackedVectorBoolType(getContext())) { const auto *RawIntTy = Value->getType(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index eba7267904fb2..427905a4ddafe 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -9955,7 +9955,7 @@ QualType Sema::BuiltinChangeSignedness(QualType BaseType, UTTKind UKind, SourceLocation Loc) { bool IsMakeSigned = UKind == UnaryTransformType::MakeSigned; if ((!BaseType->isIntegerType() && !BaseType->isEnumeralType()) || - BaseType->isBooleanType() || + (BaseType->isBooleanType() && !BaseType->isEnumeralType()) || (BaseType->isBitIntType() && BaseType->getAs<BitIntType>()->getNumBits() < 2)) { Diag(Loc, diag::err_make_signed_integral_only) `````````` </details> https://github.com/llvm/llvm-project/pull/136038 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits