forked from OSchip/llvm-project
Remove abuse of hasTrivial*, and fix miscompile wherein global arrays with
internal linkage, no uses, trivial construction, and nontrivial destruction were not emitted. llvm-svn: 167756
This commit is contained in:
parent
2b2b38d336
commit
a0e5e54e8d
|
@ -7446,27 +7446,20 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
|
|||
if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly)
|
||||
return false;
|
||||
|
||||
// Structs that have non-trivial constructors or destructors are required.
|
||||
|
||||
// FIXME: Handle references.
|
||||
// FIXME: Be more selective about which constructors we care about.
|
||||
if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
|
||||
if (RD->hasDefinition() && !(RD->hasTrivialDefaultConstructor() &&
|
||||
RD->hasTrivialCopyConstructor() &&
|
||||
RD->hasTrivialMoveConstructor() &&
|
||||
RD->hasTrivialDestructor()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Variables that can be needed in other TUs are required.
|
||||
GVALinkage L = GetGVALinkageForVariable(VD);
|
||||
if (L == GVA_Internal || L == GVA_TemplateInstantiation) {
|
||||
if (!(VD->getInit() && VD->getInit()->HasSideEffects(*this)))
|
||||
return false;
|
||||
}
|
||||
if (L != GVA_Internal && L != GVA_TemplateInstantiation)
|
||||
return true;
|
||||
|
||||
return true;
|
||||
// Variables that have destruction with side-effects are required.
|
||||
if (VD->getType().isDestructedType())
|
||||
return true;
|
||||
|
||||
// Variables that have initialization with side-effects are required.
|
||||
if (VD->getInit() && VD->getInit()->HasSideEffects(*this))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CallingConv ASTContext::getDefaultCXXMethodCallConv(bool isVariadic) {
|
||||
|
|
|
@ -43,3 +43,11 @@ T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
|||
// CHECK: call void @_ZN1TD1Ev
|
||||
// CHECK: icmp eq {{.*}} @t
|
||||
// CHECK: br i1 {{.*}}
|
||||
|
||||
static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
||||
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @_ZL2t2 to %struct.T*), i64 6
|
||||
// CHECK: call void @_ZN1TD1Ev
|
||||
// CHECK: icmp eq {{.*}} @_ZL2t
|
||||
// CHECK: br i1 {{.*}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clang_cc1 -S %s -o %t-64.s
|
||||
// RUN: %clang_cc1 -S %s -o %t-32.s
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 | FileCheck %s
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 | FileCheck %s
|
||||
|
||||
extern "C" int printf(...);
|
||||
|
||||
|
@ -16,5 +16,20 @@ struct A {
|
|||
|
||||
A a;
|
||||
|
||||
struct B {
|
||||
B() = default;
|
||||
B(const B&);
|
||||
};
|
||||
|
||||
// CHECK-NOT: _ZL1b
|
||||
static B b;
|
||||
|
||||
struct C {
|
||||
~C();
|
||||
};
|
||||
|
||||
// CHECK: _ZL1c
|
||||
static C c[4];
|
||||
|
||||
int main() {
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue