From: David Majnemer Date: Sat, 14 Mar 2015 22:24:38 +0000 (+0000) Subject: CodeGen: Correctly initialize bitfields with non-constant initializers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2f3ac362ade846532568c164bafcfb1924c78700;p=clang CodeGen: Correctly initialize bitfields with non-constant initializers It is possible to construct an initializer for a bitfield which is not constant. Instead of emitting code to initialize the field before the execution of main, clang would crash. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232285 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 54f7eee679..7406354bdc 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -383,14 +383,19 @@ bool ConstStructBuilder::Build(InitListExpr *ILE) { if (!EltInit) return false; - + if (!Field->isBitField()) { // Handle non-bitfield members. AppendField(*Field, Layout.getFieldOffset(FieldNo), EltInit); } else { // Otherwise we have a bitfield. - AppendBitField(*Field, Layout.getFieldOffset(FieldNo), - cast(EltInit)); + if (auto *CI = dyn_cast(EltInit)) { + AppendBitField(*Field, Layout.getFieldOffset(FieldNo), CI); + } else { + // We are trying to initialize a bitfield with a non-trivial constant, + // this must require run-time code. + return false; + } } } diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp index 3dc8f67303..deb923a708 100644 --- a/test/CodeGenCXX/const-init.cpp +++ b/test/CodeGenCXX/const-init.cpp @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s // CHECK: @a = global i32 10 int a = 10; @@ -76,3 +76,10 @@ int &i = reinterpret_cast(PR9558); int arr[2]; // CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) int &pastEnd = arr[2]; + +struct X { + long n : 8; +}; +long k; +X x = {(long)&k}; +// CHECK: store i8 ptrtoint (i64* @k to i8), i8* getelementptr inbounds (%struct.X, %struct.X* @x, i32 0, i32 0)