[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members

Tomas Matheson via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 18 02:45:33 PST 2021


tmatheson updated this revision to Diff 317309.
tmatheson added a comment.

Add test RUN line that checks C++11 behaviour


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93101/new/

https://reviews.llvm.org/D93101

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/CodeGenCXX/bitfield-layout.cpp


Index: clang/test/CodeGenCXX/bitfield-layout.cpp
===================================================================
--- clang/test/CodeGenCXX/bitfield-layout.cpp
+++ clang/test/CodeGenCXX/bitfield-layout.cpp
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck %s
 // RUN: %clang_cc1 %s -triple=aarch64_be-none-eabi -emit-llvm -o - -O3 | FileCheck %s
 // RUN: %clang_cc1 %s -triple=thumbv7_be-none-eabi -emit-llvm -o - -O3 | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -emit-llvm -o - -O3 -std=c++11 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-LP64 %s
 
 // CHECK-LP64: %union.Test1 = type { i32, [4 x i8] }
 union Test1 {
@@ -84,3 +85,68 @@
   // CHECK: ret i32 0
   return 0;
 }
+
+extern "C" {
+int test_trunc_int() {
+  union {
+    int i : 4; // truncated to 0b1111 == -1
+  } U = {15};  // 0b00001111
+  return U.i;
+}
+// CHECK: define dso_local i32 @test_trunc_int()
+// CHECK: ret i32 -1
+
+int test_trunc_three_bits() {
+  union {
+    int i : 3; // truncated to 0b111 == -1
+  } U = {15};  // 0b00001111
+  return U.i;
+}
+// CHECK: define dso_local i32 @test_trunc_three_bits()
+// CHECK: ret i32 -1
+
+int test_trunc_1() {
+  union {
+    int i : 1; // truncated to 0b1 == -1
+  } U = {15};  // 0b00001111
+  return U.i;
+}
+// CHECK: define dso_local i32 @test_trunc_1()
+// CHECK: ret i32 -1
+
+int test_trunc_zero() {
+  union {
+    int i : 4; // truncated to 0b0000 == 0
+  } U = {80};  // 0b01010000
+  return U.i;
+}
+// CHECK: define dso_local i32 @test_trunc_zero()
+// CHECK: ret i32 0
+
+int test_constexpr() {
+  union {
+    int i : 3;           // truncated to 0b111 == -1
+  } U = {1 + 2 + 4 + 8}; // 0b00001111
+  return U.i;
+}
+// CHECK: define dso_local i32 @test_constexpr()
+// CHECK: ret i32 -1
+
+int test_notrunc() {
+  union {
+    int i : 12;          // not truncated
+  } U = {1 + 2 + 4 + 8}; // 0b00001111
+  return U.i;
+}
+// CHECK: define dso_local i32 @test_notrunc()
+// CHECK: ret i32 15
+
+long long test_trunc_long_long() {
+  union {
+    long long i : 14; // truncated to 0b00111101001101 ==
+  } U = {0b0100111101001101};
+  return U.i;
+}
+// CHECK: define dso_local i64 @test_trunc_long_long()
+// CHECK: ret i64 3917
+}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -9798,7 +9798,10 @@
     ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
                                   isa<CXXDefaultInitExpr>(InitExpr));
 
-    return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
+    return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr) ||
+           (Field->isBitField() &&
+            truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(),
+                                  Field));
   }
 
   if (!Result.hasValue())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93101.317309.patch
Type: text/x-patch
Size: 2938 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210118/6fb366c1/attachment.bin>


More information about the cfe-commits mailing list