Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -886,24 +886,17 @@ // If this value is an array or struct with a statically determinable // constant initializer, there are optimizations we can do. - // - // TODO: We should constant-evaluate the initializer of any variable, - // as long as it is initialized by a constant expression. Currently, - // isConstantInitializer produces wrong answers for structs with - // reference or bitfield members, and a few other cases, and checking - // for POD-ness protects us from some of these. if (D.getInit() && (Ty->isArrayType() || Ty->isRecordType()) && (D.isConstexpr() || - ((Ty.isPODType(getContext()) || - getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) && - D.getInit()->isConstantInitializer(getContext(), false)))) { - + D.getInit()->isConstantInitializer(getContext(), false))) { // If the variable's a const type, and it's neither an NRVO // candidate nor a __block variable and has no mutable members, // emit it as a global instead. if (CGM.getCodeGenOpts().MergeAllConstants && !NRVO && !isByRef && CGM.isTypeConstant(Ty, true)) { EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage); + assert(cast(LocalDeclMap[&D])->isConstant() && + "Constant initializer not emitted as constant!"); emission.Address = nullptr; // signal this condition to later callbacks assert(emission.wasEmittedAsGlobal()); Index: test/CodeGenCXX/const-init-cxx11.cpp =================================================================== --- test/CodeGenCXX/const-init-cxx11.cpp +++ test/CodeGenCXX/const-init-cxx11.cpp @@ -605,6 +605,21 @@ const char *f() { return &X::p; } } +namespace ConstExprArray { + class C { + int x; + public: + constexpr C(int x) : x(x) {} + }; + void f(const C *); + void g() { +// CHECK-LABEL: _ZN14ConstExprArray1gEv +// CHECK: call void @_ZN14ConstExprArray1fEPKNS_1CE{{.*}}@_ZZN14ConstExprArray1gEvE2Cs + const C Cs[] = {1, 2, 3, 4}; + f(Cs); + } +} + // VirtualMembers::TemplateClass::templateMethod() must be defined in this TU, // not just declared. // CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(%"struct.VirtualMembers::TemplateClass"* %this) Index: test/CodeGenCXX/const-init.cpp =================================================================== --- test/CodeGenCXX/const-init.cpp +++ test/CodeGenCXX/const-init.cpp @@ -76,3 +76,24 @@ int arr[2]; // CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) int &pastEnd = arr[2]; + +struct RefMember { + int &Ref; +}; + +RefMember initRefMember() { + // CHECK: {{.*}}RefMemberInit{{.*}} = {{.*}}constant{{.*}}@arr + RefMember RefMemberInit = { arr[0] }; + return RefMemberInit; +} + +struct BitFieldMember { + int a : 1; + int b : 3; +}; + +BitFieldMember initBitFieldMember() { + // CHECK: {{.*}}BitFieldMemberInit{{.*}} = {{.*}}constant{{.*}}i8 5 + BitFieldMember BitFieldMemberInit = { 1, 2 }; + return BitFieldMemberInit; +} Index: test/CodeGenCXX/member-init-anon-union.cpp =================================================================== --- test/CodeGenCXX/member-init-anon-union.cpp +++ test/CodeGenCXX/member-init-anon-union.cpp @@ -19,7 +19,7 @@ int g() { union { int a; - int b = 81; + int b = make_a(); }; // CHECK-LABEL: define {{.*}}_Z1gv // CHECK-NOT: } @@ -49,7 +49,8 @@ // CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev" // CHECK-NOT: } -// CHECK: store i32 81 +// CHECK: call {{.*}}@_Z6make_a +// CHECK: store i32 // CHECK-LABEL: define {{.*}} @_ZN1BC2Ev( // CHECK: call void @_ZN1AC1Ev( Index: test/CodeGenCXX/microsoft-interface.cpp =================================================================== --- test/CodeGenCXX/microsoft-interface.cpp +++ test/CodeGenCXX/microsoft-interface.cpp @@ -7,6 +7,7 @@ }; struct S : I { + mutable int i; // Prevent constant folding. virtual int test() override { return I::test(); }