diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e01e53397fe3..141f35a6a0ef 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14014,25 +14014,23 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef Elements, } } -bool -Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, - bool AllowMask) const { +bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, + bool AllowMask) const { assert(ED->hasAttr() && "looking for value in non-flag enum"); + assert(ED->isCompleteDefinition() && "expected enum definition"); auto R = FlagBitsCache.insert(std::make_pair(ED, llvm::APInt())); llvm::APInt &FlagBits = R.first->second; if (R.second) { for (auto *E : ED->enumerators()) { - const auto &Val = E->getInitVal(); + const auto &EVal = E->getInitVal(); // Only single-bit enumerators introduce new flag values. - if (Val.isPowerOf2()) - FlagBits = FlagBits.zextOrSelf(Val.getBitWidth()) | Val; + if (EVal.isPowerOf2()) + FlagBits = FlagBits.zextOrSelf(EVal.getBitWidth()) | EVal; } } - llvm::APInt FlagMask = ~FlagBits.zextOrTrunc(Val.getBitWidth()); - // A value is in a flag enum if either its bits are a subset of the enum's // flag bits (the first condition) or we are allowing masks and the same is // true of its complement (the second condition). When masks are allowed, we @@ -14041,11 +14039,8 @@ Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, // While it's true that any value could be used as a mask, the assumption is // that a mask will have all of the insignificant bits set. Anything else is // likely a logic error. - if (!(FlagMask & Val) || - (AllowMask && !(FlagMask & ~Val))) - return true; - - return false; + llvm::APInt FlagMask = ~FlagBits.zextOrTrunc(Val.getBitWidth()); + return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val)); } void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, @@ -14261,6 +14256,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->setType(NewTy); } + Enum->completeDefinition(BestType, BestPromotionType, + NumPositiveBits, NumNegativeBits); + + CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType); + if (Enum->hasAttr()) { for (Decl *D : Elements) { EnumConstantDecl *ECD = cast_or_null(D); @@ -14274,11 +14274,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, } } - Enum->completeDefinition(BestType, BestPromotionType, - NumPositiveBits, NumNegativeBits); - - CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType); - // Now that the enum type is defined, ensure it's not been underaligned. if (Enum->hasAttrs()) CheckAlignasUnderalignment(Enum);