]> granicus.if.org Git - clang/commitdiff
Allow -1 to assign max value to unsigned bitfields.
authorRichard Trieu <rtrieu@google.com>
Fri, 5 Aug 2016 02:39:30 +0000 (02:39 +0000)
committerRichard Trieu <rtrieu@google.com>
Fri, 5 Aug 2016 02:39:30 +0000 (02:39 +0000)
Silence the -Wbitfield-constant-conversion warning for when -1 or other
negative values are assigned to unsigned bitfields, provided that the bitfield
is wider than the minimum number of bits needed to encode the negative value.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@277796 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/bitfield.c
test/Sema/constant-conversion.c

index a534ead73dfd4a152f1c32b3fd2de858a1b525a2..c7163943cfbc66370e1f7728aa2bcf6532644697 100644 (file)
@@ -7827,6 +7827,12 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
   unsigned OriginalWidth = Value.getBitWidth();
   unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context);
 
+  if (Value.isSigned() && Value.isNegative())
+    if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
+      if (UO->getOpcode() == UO_Minus)
+        if (isa<IntegerLiteral>(UO->getSubExpr()))
+          OriginalWidth = Value.getMinSignedBits();
+
   if (OriginalWidth <= FieldWidth)
     return false;
 
index 810dc798eaa5c17729005483ddc16a8efef6a74f..d625366e4e1f26b71f16bcef42758ff754a27033 100644 (file)
@@ -64,7 +64,7 @@ typedef signed Signed;
 
 struct Test5 { unsigned n : 2; } t5;
 // Bitfield is unsigned
-struct Test5 sometest5 = {-1}; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -1 to 3}}
+struct Test5 sometest5 = {-1};
 typedef __typeof__(+t5.n) Signed;  // ... but promotes to signed.
 
 typedef __typeof__(t5.n + 0) Signed; // Arithmetic promotes.
index b717f93253364f48b712ab933902be84e2017d5b..203e7373897c3d70f5444a97200be3f91555abfe 100644 (file)
@@ -113,3 +113,15 @@ void test9() {
 
   char array_init[] = { 255, 127, 128, 129, 0 };
 }
+
+void test10() {
+  struct S {
+    unsigned a : 4;
+  } s;
+  s.a = -1;
+  s.a = 15;
+  s.a = -8;
+
+  s.a = -9;  // expected-warning{{implicit truncation from 'int' to bitfield changes value from -9 to 7}}
+  s.a = 16;  // expected-warning{{implicit truncation from 'int' to bitfield changes value from 16 to 0}}
+}