[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG01b9e613c28b: [Clang][Codegen] Truncate initializers of union bitfield members (authored by tmatheson). 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 0b == -1 + } const U = {15}; // 0b + 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 + } const U = {15}; // 0b + 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 + } const U = {15}; // 0b + 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 0b == 0 + } const U = {80}; // 0b0101 + 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 + } const U = {1 + 2 + 4 + 8}; // 0b + return U.i; +} +// CHECK: define dso_local i32 @test_constexpr() +// CHECK: ret i32 -1 + +int test_notrunc() { + union { +int i : 12; // not truncated + } const U = {1 + 2 + 4 + 8}; // 0b + 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 0b0001001101 == + } const U = {0b010001001101}; + 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,14 @@ ThisOverrideRAII ThisOverride(*Info.CurrentCall, , isa(InitExpr)); -return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr); +if (EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) { + if (Field->isBitField()) +return truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(), + Field); + return true; +} + +return false; } if (!Result.hasValue()) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
pratlucas accepted this revision. pratlucas added a comment. This revision is now accepted and ready to land. The truncate conditions look a lot better and the test coverage seems reasonable now. LGTM. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93101/new/ https://reviews.llvm.org/D93101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
tmatheson marked 2 inline comments as done. tmatheson added a comment. Ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93101/new/ https://reviews.llvm.org/D93101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
tmatheson marked 3 inline comments as done. tmatheson added inline comments. Comment at: clang/lib/AST/ExprConstant.cpp:9801-9804 +return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr) || + (Field->isBitField() && +truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(), + Field)); rsmith wrote: > Shouldn't this be `&&` not `||`? These functions return `true` if they > succeed (unlike the convention in `Sema` where `true` means an error > diagnostic was produced). You are correct. I have updated the logic to be simpler to follow as well. Comment at: clang/test/CodeGenCXX/bitfield-layout.cpp:88-95 +// CHECK: define i32 @_Z10test_truncv() +int test_trunc() { + union { +int i : 4; + } U = {15}; + return U.i; + // CHECK: ret i32 -1 joechrisellis wrote: > I'd like to see some more tests that check the truncation behaviour. My > understanding is that this is trucating to -1 because of two's complement? > How about something like: > > ``` > int test_trunc() { > union { > int i : 4; > } U = {80}; > return U.i; > // CHECK: ret i32 0 > } > ``` > > Am I understanding the behaviour correctly? > > Some comments about what is actually happening on the bit-level to get this > result would also be nice. Yes that is correct. I have added some new test cases and comments to make it clear what they are testing for. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93101/new/ https://reviews.llvm.org/D93101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
tmatheson updated this revision to Diff 317340. tmatheson added a comment. Make unions in test cases const, and clarify logic 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 0b == -1 + } const U = {15}; // 0b + 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 + } const U = {15}; // 0b + 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 + } const U = {15}; // 0b + 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 0b == 0 + } const U = {80}; // 0b0101 + 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 + } const U = {1 + 2 + 4 + 8}; // 0b + return U.i; +} +// CHECK: define dso_local i32 @test_constexpr() +// CHECK: ret i32 -1 + +int test_notrunc() { + union { +int i : 12; // not truncated + } const U = {1 + 2 + 4 + 8}; // 0b + 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 0b0001001101 == + } const U = {0b010001001101}; + 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,14 @@ ThisOverrideRAII ThisOverride(*Info.CurrentCall, , isa(InitExpr)); -return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr); +if (EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) { + if (Field->isBitField()) +return truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(), + Field); + return true; +} + +return false; } if (!Result.hasValue()) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
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 0b == -1 + } U = {15}; // 0b + 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}; // 0b + 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}; // 0b + 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 0b == 0 + } U = {80}; // 0b0101 + 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}; // 0b + 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}; // 0b + 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 0b0001001101 == + } U = {0b010001001101}; + 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, , isa(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 @@ -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 0b == -1 + } U = {15}; // 0b + 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}; // 0b + 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}; // 0b + 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 0b == 0 + } U = {80}; // 0b0101 + 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}; // 0b + return
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
tmatheson updated this revision to Diff 317306. tmatheson added a comment. Added more test cases and explanatory comments 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 @@ -84,3 +84,68 @@ // CHECK: ret i32 0 return 0; } + +extern "C" { +int test_trunc_int() { + union { +int i : 4; // truncated to 0b == -1 + } U = {15}; // 0b + 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}; // 0b + 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}; // 0b + 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 0b == 0 + } U = {80}; // 0b0101 + 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}; // 0b + 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}; // 0b + 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 0b0001001101 == + } U = {0b010001001101}; + 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, , isa(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,68 @@ // CHECK: ret i32 0 return 0; } + +extern "C" { +int test_trunc_int() { + union { +int i : 4; // truncated to 0b == -1 + } U = {15}; // 0b + 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}; // 0b + 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}; // 0b + 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 0b == 0 + } U = {80}; // 0b0101 + 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}; // 0b + 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}; // 0b + 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 0b0001001101 == + } U = {0b010001001101}; + 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, , isa(InitExpr)); -return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr); +return EvaluateInPlace(Result.getUnionValue(), Info, Subobject,
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
rsmith added inline comments. Comment at: clang/lib/AST/ExprConstant.cpp:9801-9804 +return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr) || + (Field->isBitField() && +truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(), + Field)); Shouldn't this be `&&` not `||`? These functions return `true` if they succeed (unlike the convention in `Sema` where `true` means an error diagnostic was produced). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93101/new/ https://reviews.llvm.org/D93101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
joechrisellis added inline comments. Comment at: clang/lib/AST/ExprConstant.cpp:9803-9804 + (Field->isBitField() && +truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(), + Field)); } nit: I would prefer this: ``` if (Field->isBitField() && truncateBitfieldValue(Info, InitExpr, Result.getUnionValue(), Field)) return true; return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr); ``` It feels more in-line with the rest of the function. But it is okay if you want to ignore this too. Comment at: clang/test/CodeGenCXX/bitfield-layout.cpp:88-95 +// CHECK: define i32 @_Z10test_truncv() +int test_trunc() { + union { +int i : 4; + } U = {15}; + return U.i; + // CHECK: ret i32 -1 I'd like to see some more tests that check the truncation behaviour. My understanding is that this is trucating to -1 because of two's complement? How about something like: ``` int test_trunc() { union { int i : 4; } U = {80}; return U.i; // CHECK: ret i32 0 } ``` Am I understanding the behaviour correctly? Some comments about what is actually happening on the bit-level to get this result would also be nice. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93101/new/ https://reviews.llvm.org/D93101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
tmatheson added a comment. Ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93101/new/ https://reviews.llvm.org/D93101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
tmatheson updated this revision to Diff 311529. tmatheson added a comment. Rebased 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 @@ -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, , isa(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, , isa(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
[PATCH] D93101: [Clang][Codegen] Truncate initializers of union bitfield members
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, , isa(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, , isa(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