This revision was automatically updated to reflect the committed changes.
Closed by commit rL287177: Add warning when assigning enums to bitfields
without an explicit unsigned… (authored by rnk).
Changed prior to commit:
https://reviews.llvm.org/D24289?vs=70760&id=78281#toc
Repository:
rL LLVM
https://reviews.llvm.org/D24289
Files:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/SemaCXX/warn-msvc-enum-bitfield.cpp
Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3020,6 +3020,10 @@
"cast to %1 from smaller integer type %0">,
InGroup<IntToVoidPointerCast>;
+def warn_no_underlying_type_specified_for_enum_bitfield : Warning<
+ "enums in the Microsoft ABI are signed integers by default; consider giving "
+ "the enum %0 an unsigned underlying type to make this code portable">,
+ InGroup<DiagGroup<"signed-enum-bitfield">>, DefaultIgnore;
def warn_attribute_packed_for_bitfield : Warning<
"'packed' attribute was ignored on bit-fields with single-byte alignment "
"in older versions of GCC and Clang">,
Index: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td
@@ -543,6 +543,7 @@
def CharSubscript : DiagGroup<"char-subscripts">;
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
+def SignedEnumBitfield : DiagGroup<"signed-enum-bitfield">;
// Unreachable code warning groups.
//
@@ -661,6 +662,7 @@
ReturnType,
SelfAssignment,
SelfMove,
+ SignedEnumBitfield,
SizeofArrayArgument,
SizeofArrayDecay,
StringPlusInt,
Index: cfe/trunk/test/SemaCXX/warn-msvc-enum-bitfield.cpp
===================================================================
--- cfe/trunk/test/SemaCXX/warn-msvc-enum-bitfield.cpp
+++ cfe/trunk/test/SemaCXX/warn-msvc-enum-bitfield.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -Wsigned-enum-bitfield -verify %s --std=c++11
+
+// Enums used in bitfields with no explicitly specified underlying type.
+void test0() {
+ enum E { E1, E2 };
+ enum F { F1, F2 };
+ struct { E e1 : 1; E e2; F f1 : 1; F f2; } s;
+
+ s.e1 = E1; // expected-warning {{enums in the Microsoft ABI are signed integers by default; consider giving the enum E an unsigned underlying type to make this code portable}}
+ s.f1 = F1; // expected-warning {{enums in the Microsoft ABI are signed integers by default; consider giving the enum F an unsigned underlying type to make this code portable}}
+
+ s.e2 = E2;
+ s.f2 = F2;
+}
+
+// Enums used in bitfields with an explicit signed underlying type.
+void test1() {
+ enum E : signed { E1, E2 };
+ enum F : long { F1, F2 };
+ struct { E e1 : 1; E e2; F f1 : 1; F f2; } s;
+
+ s.e1 = E1;
+ s.f1 = F1;
+
+ s.e2 = E2;
+ s.f2 = F2;
+}
+
+// Enums used in bitfields with an explicitly unsigned underlying type.
+void test3() {
+ enum E : unsigned { E1, E2 };
+ enum F : unsigned long { F1, F2 };
+ struct { E e1 : 1; E e2; F f1 : 1; F f2; } s;
+
+ s.e1 = E1;
+ s.f1 = F1;
+
+ s.e2 = E2;
+ s.f2 = F2;
+}
Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -8518,6 +8518,24 @@
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 @@
// 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);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits