forked from OSchip/llvm-project
[CodeGen] When promoting a reference temporary to a global use the inner type to fold it.
The MaterializeTemporaryExpr can have a different type than the inner expression, miscompiling the constant. PR23165. llvm-svn: 234499
This commit is contained in:
parent
504a5dccc4
commit
b2b81439a3
|
@ -309,12 +309,13 @@ createReferenceTemporary(CodeGenFunction &CGF,
|
||||||
(M->getType()->isArrayType() || M->getType()->isRecordType()) &&
|
(M->getType()->isArrayType() || M->getType()->isRecordType()) &&
|
||||||
CGF.CGM.isTypeConstant(M->getType(), true))
|
CGF.CGM.isTypeConstant(M->getType(), true))
|
||||||
if (llvm::Constant *Init =
|
if (llvm::Constant *Init =
|
||||||
CGF.CGM.EmitConstantExpr(Inner, M->getType(), &CGF)) {
|
CGF.CGM.EmitConstantExpr(Inner, Inner->getType(), &CGF)) {
|
||||||
auto *GV = new llvm::GlobalVariable(
|
auto *GV = new llvm::GlobalVariable(
|
||||||
CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
|
CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
|
||||||
llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");
|
llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");
|
||||||
GV->setAlignment(
|
GV->setAlignment(CGF.getContext()
|
||||||
CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity());
|
.getTypeAlignInChars(Inner->getType())
|
||||||
|
.getQuantity());
|
||||||
// FIXME: Should we put the new global into a COMDAT?
|
// FIXME: Should we put the new global into a COMDAT?
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
|
// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
|
||||||
|
|
||||||
|
// CHECK: private constant { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN7PR2316510ChildClassE, i64 0, i64 2) }, align 4
|
||||||
|
|
||||||
namespace reference {
|
namespace reference {
|
||||||
struct A {
|
struct A {
|
||||||
int i1, i2;
|
int i1, i2;
|
||||||
|
@ -79,3 +81,22 @@ namespace reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PR23165 {
|
||||||
|
struct AbstractClass {
|
||||||
|
virtual void foo() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChildClass : public AbstractClass {
|
||||||
|
virtual void foo() const {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void helper(const AbstractClass ¶m) {
|
||||||
|
param.foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE(%{{.*}} bitcast ({ i8** }* @{{.*}} to %{{.*}}*))
|
||||||
|
helper(ChildClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue