From: Richard Smith Date: Fri, 21 Dec 2012 03:17:28 +0000 (+0000) Subject: Reinstate r170806, reverted in r170835, with a fix use i1 instead of i8 for a value... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0dbe2fb7758fe64568206b5bc0f1c5b106b9c806;p=clang Reinstate r170806, reverted in r170835, with a fix use i1 instead of i8 for a value-initialized bool! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170837 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index c7f65bf420..0c1e23965d 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -931,7 +931,7 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { // FIXME: Are initializers affected by volatile? if (Dest.isZeroed() && isSimpleZero(E, CGF)) { // Storing "i32 0" to a zero'd memory location is a noop. - } else if (isa(E)) { + } else if (isa(E) || isa(E)) { EmitNullInitializationToLValue(LV); } else if (type->isReferenceType()) { RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); @@ -960,8 +960,8 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) { return; if (!CGF.hasAggregateLLVMType(type)) { - // For non-aggregates, we can store zero. - llvm::Value *null = llvm::Constant::getNullValue(CGF.ConvertType(type)); + // For non-aggregates, we can store the appropriate null constant. + llvm::Value *null = CGF.CGM.EmitNullConstant(type); // Note that the following is not equivalent to // EmitStoreThroughBitfieldLValue for ARC types. if (lv.isBitField()) { diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 9071e693f9..61126e101a 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -266,7 +266,7 @@ public: Value *VisitInitListExpr(InitListExpr *E); Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { - return CGF.CGM.EmitNullConstant(E->getType()); + return EmitNullValue(E->getType()); } Value *VisitExplicitCastExpr(ExplicitCastExpr *E) { if (E->getType()->isVariablyModifiedType()) @@ -800,10 +800,7 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, } Value *ScalarExprEmitter::EmitNullValue(QualType Ty) { - if (const MemberPointerType *MPT = Ty->getAs()) - return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT); - - return llvm::Constant::getNullValue(ConvertType(Ty)); + return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty); } /// \brief Emit a sanitization check for the given "binary" operation (which diff --git a/test/CodeGenCXX/cxx0x-initializer-array.cpp b/test/CodeGenCXX/cxx0x-initializer-array.cpp index df689978a8..5e81ba1ff9 100644 --- a/test/CodeGenCXX/cxx0x-initializer-array.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-array.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -S -emit-llvm -o - %s | FileCheck %s +// CHECK: @[[THREE_NULL_MEMPTRS:.*]] = private constant [3 x i32] [i32 -1, i32 -1, i32 -1] + struct A { int a[1]; }; typedef A x[]; int f() { @@ -7,4 +9,42 @@ int f() { // CHECK: define i32 @_Z1fv // CHECK: store i32 1 // (It's okay if the output changes here, as long as we don't crash.) + return 0; +} + +namespace ValueInitArrayOfMemPtr { + struct S {}; + typedef int (S::*p); + typedef p a[3]; + void f(const a &); + + struct Agg1 { + int n; + p x; + }; + + struct Agg2 { + int n; + a x; + }; + + struct S1 { + p x; + S1(); + }; + + // CHECK: define void @_ZN22ValueInitArrayOfMemPtr1fEi + void f(int n) { + Agg1 a = { n }; + // CHECK: store i32 -1, + + Agg2 b = { n }; + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* bitcast ([3 x i32]* @[[THREE_NULL_MEMPTRS]] to i8*), i32 12, i32 4, i1 false) + } + + // CHECK: define void @_ZN22ValueInitArrayOfMemPtr1gEv + void g() { + // CHECK: store i32 -1, + f(a{}); + } } diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp index 6e60f80110..60dca99045 100644 --- a/test/CodeGenCXX/value-init.cpp +++ b/test/CodeGenCXX/value-init.cpp @@ -256,6 +256,12 @@ namespace PR11124 { // CHECK-NEXT: call void @_ZN7PR111242B2C2Ev } +// Ensure we produce an i1 here, and don't assert. +// CHECK: define void @_Z9r170806_bv( +// CHECK: call void @_Z9r170806_ab(i1 zeroext false) +void r170806_a(bool b = bool()); +void r170806_b() { r170806_a(); } + // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr // CHECK: call void @llvm.memset.p0i8.i64 // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev