Commit 82afc9b1 authored by Shawn Zhong's avatar Shawn Zhong Committed by Aaron Ballman
Browse files

Fix -Wbitfield-constant-conversion on 1-bit signed bitfield

A one-bit signed bit-field can only hold the values 0 and -1; this
corrects the diagnostic behavior accordingly.

Fixes #53253
Differential Revision: https://reviews.llvm.org/D131255
parent e486e48c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -82,6 +82,9 @@ Improvements to Clang's diagnostics
- ``-Wformat`` now recognizes ``%b`` for the ``printf``/``scanf`` family of
  functions and ``%B`` for the ``printf`` family of functions. Fixes
  `Issue 56885: <https://github.com/llvm/llvm-project/issues/56885>`_.
- ``-Wbitfield-constant-conversion`` now diagnoses implicit truncation when 1 is
  assigned to a 1-bit signed integer bitfield. This fixes
  `Issue 53253 <https://github.com/llvm/llvm-project/issues/53253>`_.

Non-comprehensive list of changes in this release
-------------------------------------------------
+0 −5
Original line number Diff line number Diff line
@@ -13064,11 +13064,6 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
  if (llvm::APSInt::isSameValue(Value, TruncatedValue))
    return false;
  // Special-case bitfields of width 1: booleans are naturally 0/1, and
  // therefore don't strictly fit into a signed bitfield of width 1.
  if (FieldWidth == 1 && Value == 1)
    return false;
  std::string PrettyValue = toString(Value, 10);
  std::string PrettyTrunc = toString(TruncatedValue, 10);
+5 −5
Original line number Diff line number Diff line
@@ -9,11 +9,11 @@ struct A {
  int [[]] c : 1; // OK, attribute applies to the type.
  int : 2 = 1; // expected-error {{anonymous bit-field cannot have a default member initializer}}
  int : 0 { 1 }; // expected-error {{anonymous bit-field cannot have a default member initializer}}
  int : 0, d : 1 = 1;
  unsigned int : 0, d : 1 = 1;
  int : 1 = 12, e : 1; // expected-error {{anonymous bit-field cannot have a default member initializer}}
  int : 0, f : 1 = 1;
  int g [[]] : 1 = 1;
  int h [[]] : 1 {1};
  int i : foo() = foo();
  unsigned int : 0, f : 1 = 1;
  unsigned int g [[]] : 1 = 1;
  unsigned int h [[]] : 1 {1};
  unsigned int i : foo() = foo();
  int j, [[]] k; // expected-error {{an attribute list cannot appear here}}
};
+3 −3
Original line number Diff line number Diff line
@@ -911,9 +911,9 @@ namespace dr674 { // dr674: 8
namespace dr675 { // dr675: dup 739
  template<typename T> struct A { T n : 1; };
#if __cplusplus >= 201103L
  static_assert(A<char>{1}.n < 0, "");
  static_assert(A<int>{1}.n < 0, "");
  static_assert(A<long long>{1}.n < 0, "");
  static_assert(A<char>{1}.n < 0, ""); // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
  static_assert(A<int>{1}.n < 0, ""); // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
  static_assert(A<long long>{1}.n < 0, ""); // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
#endif
}

+16 −0
Original line number Diff line number Diff line
@@ -87,3 +87,19 @@ int g3(void) {
// PATH: ret i32 1
  return f3(20) + 130725747;
}

static int f4(void) {
  struct s5 {
    int b:1;
  } x;
  x.b = 1;
  return x.b;
}

int g4(void) {
// CHECK-LABEL: @g4()
// CHECK: ret i32 1
// PATH-LABEL: @g4()
// PATH: ret i32 1
  return f4() + 2;
}
Loading