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 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())
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 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())
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits