tmatheson created this revision.
tmatheson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If an initial value is given for a bitfield that does not fit in the
bitfield, the value should be truncated. Constant folding for
expressions did not account for this truncation in the case of union
member functions, despite a warning being emitted. In some contexts,
evaluation of expressions was not enabled unless C++11, ROPI or RWPI
was enabled.


Repository:
  rG LLVM Github Monorepo

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
@@ -84,3 +84,12 @@
   // CHECK: ret i32 0
   return 0;
 }
+
+// CHECK: define i32 @_Z10test_truncv()
+int test_trunc() {
+  union {
+    int i : 4;
+  } U = {15};
+  return U.i;
+  // CHECK: ret i32 -1
+}
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())


Index: clang/test/CodeGenCXX/bitfield-layout.cpp
===================================================================
--- clang/test/CodeGenCXX/bitfield-layout.cpp
+++ clang/test/CodeGenCXX/bitfield-layout.cpp
@@ -84,3 +84,12 @@
   // CHECK: ret i32 0
   return 0;
 }
+
+// CHECK: define i32 @_Z10test_truncv()
+int test_trunc() {
+  union {
+    int i : 4;
+  } U = {15};
+  return U.i;
+  // CHECK: ret i32 -1
+}
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())
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to