diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1211,15 +1211,6 @@ return Visit(DIE->getExpr(), T); } - llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E, QualType T) { - return Visit(E->getSubExpr(), T); - } - - llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E, - QualType T) { - return Visit(E->getSubExpr(), T); - } - llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) { auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType()); assert(CAT && "can't emit array init for non-constant-bound array"); @@ -1657,18 +1648,6 @@ // Try to emit the initializer. Note that this can allow some things that // are not allowed by tryEmitPrivateForMemory alone. - if (APValue *value = D.evaluateValue()) - return tryEmitPrivateForMemory(*value, destType); - - // FIXME: Implement C++11 [basic.start.init]p2: if the initializer of a - // reference is a constant expression, and the reference binds to a temporary, - // then constant initialization is performed. ConstExprEmitter will - // incorrectly emit a prvalue constant in this case, and the calling code - // interprets that as the (pointer) value of the reference, rather than the - // desired value of the referee. - if (destType->isReferenceType()) - return nullptr; - const Expr *E = D.getInit(); assert(E && "No initializer to emit"); @@ -1676,6 +1655,10 @@ if (llvm::Constant *C = ConstExprEmitter(*this).Visit(const_cast(E), nonMemoryDestType)) return emitForMemory(C, destType); + + if (APValue *value = D.evaluateValue()) + return tryEmitPrivateForMemory(*value, destType); + return nullptr; } diff --git a/clang/test/CodeGenCXX/const-init-cxx1y.cpp b/clang/test/CodeGenCXX/const-init-cxx1y.cpp --- a/clang/test/CodeGenCXX/const-init-cxx1y.cpp +++ b/clang/test/CodeGenCXX/const-init-cxx1y.cpp @@ -34,8 +34,8 @@ // 'c.temporary', not the value as modified by the partial evaluation within // the initialization of 'c.x'. A c = { 10, (++c.temporary, b.x) }; + // CHECK: @_ZN21ModifyStaticTemporary1cE = global %"struct.ModifyStaticTemporary::A" zeroinitializer // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = internal global i32 10 - // CHECK: @_ZN21ModifyStaticTemporary1cE ={{.*}} global {{.*}} zeroinitializer } // CHECK: @_ZGRN28VariableTemplateWithConstRef1iIvEE_ = linkonce_odr constant i32 5, align 4 diff --git a/clang/test/CodeGenCXX/designated-init.cpp b/clang/test/CodeGenCXX/designated-init.cpp --- a/clang/test/CodeGenCXX/designated-init.cpp +++ b/clang/test/CodeGenCXX/designated-init.cpp @@ -4,7 +4,8 @@ struct A { int x, y[3]; }; struct B { A a; }; -// CHECK: @b ={{.*}} global %{{[^ ]*}} { %{{[^ ]*}} { i32 1, [3 x i32] [i32 2, i32 5, i32 4] } } +// CHECK: @b = global %struct.B zeroinitializer, align 4 + B b = {(A){1, 2, 3, 4}, .a.y[1] = 5}; union U { @@ -19,10 +20,10 @@ C c; }; -// CHECK: @d1 = {{.*}} { i32 1, [3 x %[[U:.*]]] [%[[U]] { i32 2 }, %[[U]] { i32 5 }, %[[U]] { i32 4 }] } +// CHECK: @d1 = global %struct.D zeroinitializer, align 4 D d1 = {(C){1, {{.n=2}, {.f=3}, {.n=4}}}, .c.u[1].n = 5}; -// CHECK: @d2 = {{.*}} { i32 1, { %[[U]], float, %[[U]] } { %[[U]] { i32 2 }, float 5.{{0*}}e+00, %[[U]] { i32 4 } } } +// CHECK: @d2 = global %struct.D zeroinitializer, align 4 D d2 = {(C){1, 2, 3, 4}, .c.u[1].f = 5}; struct Bitfield { @@ -34,7 +35,7 @@ int n; Bitfield b; }; -// CHECK: @bitfield = {{.*}} { i32 1, { i8, i8, [2 x i8] } { i8 42, i8 2, [2 x i8] undef } } +// CHECK: @bitfield = global %struct.WithBitfield zeroinitializer, align 4 WithBitfield bitfield = {1, (Bitfield){2, 3, 4}, .b.b = 5}; struct String { @@ -43,7 +44,7 @@ struct WithString { String str; }; -// CHECK: @string = {{.*}} [12 x i8] c"Hello World\00" } } +// CHECK: @string = global %struct.WithString zeroinitializer, align 1 WithString string = {(String){"hello world"}, .str.buffer[0] = 'H', .str.buffer[6] = 'W'}; struct LargeArray { @@ -52,7 +53,7 @@ struct WithLargeArray { LargeArray arr; }; -// CHECK: @large ={{.*}} global { { <{ [11 x i32], [4085 x i32] }> } } { { <{ [11 x i32], [4085 x i32] }> } { <{ [11 x i32], [4085 x i32] }> <{ [11 x i32] [i32 1, i32 2, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 10], [4085 x i32] zeroinitializer }> } } +// CHECK: @large = global %struct.WithLargeArray zeroinitializer, align 4 WithLargeArray large = {(LargeArray){1, 2, 3}, .arr.arr[10] = 10}; union OverwritePaddingWithBitfield { @@ -62,5 +63,6 @@ struct WithOverwritePaddingWithBitfield { OverwritePaddingWithBitfield a; }; -// CHECK: @overwrite_padding ={{.*}} global { { i8, i8 } } { { i8, i8 } { i8 3, i8 1 } } +// CHECK: @overwrite_padding = global %struct.WithOverwritePaddingWithBitfield zeroinitializer, align 1 + WithOverwritePaddingWithBitfield overwrite_padding = {(OverwritePaddingWithBitfield){1}, .a.bitfield = 3};