aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp93
1 files changed, 12 insertions, 81 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 007470344f19..b556f18b7632 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8828,11 +8828,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
});
if (Res.isInvalid()) {
VDecl->setInvalidDecl();
- return;
- }
- if (Res.get() != Args[Idx])
+ } else if (Res.get() != Args[Idx]) {
Args[Idx] = Res.get();
+ }
}
+ if (VDecl->isInvalidDecl())
+ return;
InitializationSequence InitSeq(*this, Entity, Kind, Args);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
@@ -13519,49 +13520,6 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
}
}
-bool
-Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
- bool AllowMask) const {
- FlagEnumAttr *FEAttr = ED->getAttr<FlagEnumAttr>();
- assert(FEAttr && "looking for value in non-flag enum");
-
- llvm::APInt FlagMask = ~FEAttr->getFlagBits();
- unsigned Width = FlagMask.getBitWidth();
-
- // We will try a zero-extended value for the regular check first.
- llvm::APInt ExtVal = Val.zextOrSelf(Width);
-
- // 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
- // allow the common idiom of ~(enum1 | enum2) to be a valid enum value.
- //
- // 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 & ExtVal))
- return true;
-
- if (AllowMask) {
- // Try a one-extended value instead. This can happen if the enum is wider
- // than the constant used, in C with extensions to allow for wider enums.
- // The mask will still have the correct behaviour, so we give the user the
- // benefit of the doubt.
- //
- // FIXME: This heuristic can cause weird results if the enum was extended
- // to a larger type and is signed, because then bit-masks of smaller types
- // that get extended will fall out of range (e.g. ~0x1u). We currently don't
- // detect that case and will get a false positive for it. In most cases,
- // though, it can be fixed by making it a signed type (e.g. ~0x1), so it may
- // be fine just to accept this as a warning.
- ExtVal |= llvm::APInt::getHighBitsSet(Width, Width - Val.getBitWidth());
- if (!(FlagMask & ~ExtVal))
- return true;
- }
-
- return false;
-}
-
void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
SourceLocation RBraceLoc, Decl *EnumDeclX,
ArrayRef<Decl *> Elements,
@@ -13647,8 +13605,10 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
BestPromotionType = Context.getPromotedIntegerType(BestType);
else
BestPromotionType = BestType;
-
- BestWidth = Context.getIntWidth(BestType);
+ // We don't need to set BestWidth, because BestType is going to be the type
+ // of the enumerators, but we do anyway because otherwise some compilers
+ // warn that it might be used uninitialized.
+ BestWidth = CharWidth;
}
else if (NumNegativeBits) {
// If there is a negative value, figure out the smallest integer type (of
@@ -13713,15 +13673,10 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
}
}
- FlagEnumAttr *FEAttr = Enum->getAttr<FlagEnumAttr>();
- if (FEAttr)
- FEAttr->getFlagBits() = llvm::APInt(BestWidth, 0);
-
// Loop over all of the enumerator constants, changing their types to match
- // the type of the enum if needed. If we have a flag type, we also prepare the
- // FlagBits cache.
- for (auto *D : Elements) {
- auto *ECD = cast_or_null<EnumConstantDecl>(D);
+ // the type of the enum if needed.
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+ EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue; // Already issued a diagnostic.
// Standard C says the enumerators have int type, but we allow, as an
@@ -13751,7 +13706,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
// enum-specifier, each enumerator has the type of its
// enumeration.
ECD->setType(EnumType);
- goto flagbits;
+ continue;
} else {
NewTy = BestType;
NewWidth = BestWidth;
@@ -13778,32 +13733,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
ECD->setType(EnumType);
else
ECD->setType(NewTy);
-
-flagbits:
- // Check to see if we have a constant with exactly one bit set. Note that x
- // & (x - 1) will be nonzero if and only if x has more than one bit set.
- if (FEAttr) {
- llvm::APInt ExtVal = InitVal.zextOrSelf(BestWidth);
- if (ExtVal != 0 && !(ExtVal & (ExtVal - 1))) {
- FEAttr->getFlagBits() |= ExtVal;
- }
- }
- }
-
- if (FEAttr) {
- for (Decl *D : Elements) {
- EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D);
- if (!ECD) continue; // Already issued a diagnostic.
-
- llvm::APSInt InitVal = ECD->getInitVal();
- if (InitVal != 0 && !IsValueInFlagEnum(Enum, InitVal, true))
- Diag(ECD->getLocation(), diag::warn_flag_enum_constant_out_of_range)
- << ECD << Enum;
- }
}
-
-
Enum->completeDefinition(BestType, BestPromotionType,
NumPositiveBits, NumNegativeBits);