diff options
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 56bc3ace139..c1db062f35d 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8518,6 +8518,24 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, return false; // White-list bool bitfields. + QualType BitfieldType = Bitfield->getType(); + if (BitfieldType->isBooleanType()) + return false; + + if (BitfieldType->isEnumeralType()) { + EnumDecl *BitfieldEnumDecl = BitfieldType->getAs<EnumType>()->getDecl(); + // If the underlying enum type was not explicitly specified as an unsigned + // type and the enum contain only positive values, MSVC++ will cause an + // inconsistency by storing this as a signed type. + if (S.getLangOpts().CPlusPlus11 && + !BitfieldEnumDecl->getIntegerTypeSourceInfo() && + BitfieldEnumDecl->getNumPositiveBits() > 0 && + BitfieldEnumDecl->getNumNegativeBits() == 0) { + S.Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield) + << BitfieldEnumDecl->getNameAsString(); + } + } + if (Bitfield->getType()->isBooleanType()) return false; @@ -8547,7 +8565,7 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, // Compute the value which the bitfield will contain. llvm::APSInt TruncatedValue = Value.trunc(FieldWidth); - TruncatedValue.setIsSigned(Bitfield->getType()->isSignedIntegerType()); + TruncatedValue.setIsSigned(BitfieldType->isSignedIntegerType()); // Check whether the stored value is equal to the original value. TruncatedValue = TruncatedValue.extend(OriginalWidth); |