зеркало из https://github.com/microsoft/clang-1.git
Right, there are *two* cases of pr-value class-type expressions that don't
derive from temporaries of the same type. Black-list member expressions as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114071 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b25938303d
Коммит
19e60ad937
|
@ -1659,9 +1659,10 @@ bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
|
|||
// Temporaries are by definition pr-values of class type.
|
||||
if (!E->Classify(C).isPRValue()) return false;
|
||||
|
||||
// Black-list implicit derived-to-base conversions, which are the
|
||||
// only way we can get a pr-value of class type that doesn't refer
|
||||
// to a temporary of that type.
|
||||
// Black-list a few cases which yield pr-values of class type that don't
|
||||
// refer to temporaries of that type:
|
||||
|
||||
// - implicit derived-to-base conversions
|
||||
if (isa<ImplicitCastExpr>(E)) {
|
||||
switch (cast<ImplicitCastExpr>(E)->getCastKind()) {
|
||||
case CK_DerivedToBase:
|
||||
|
@ -1672,6 +1673,10 @@ bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
|
|||
}
|
||||
}
|
||||
|
||||
// - member expressions (all)
|
||||
if (isa<MemberExpr>(E))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -344,6 +344,7 @@ namespace Elision {
|
|||
|
||||
void foo();
|
||||
A fooA();
|
||||
void takeA(A a);
|
||||
|
||||
// CHECK: define void @_ZN7Elision5test0Ev()
|
||||
void test0() {
|
||||
|
@ -441,4 +442,37 @@ namespace Elision {
|
|||
|
||||
// CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
|
||||
}
|
||||
|
||||
// rdar://problem/8433352
|
||||
// CHECK: define void @_ZN7Elision5test5Ev([[A]]* sret
|
||||
struct B { A a; B(); };
|
||||
A test5() {
|
||||
// CHECK: [[AT0:%.*]] = alloca [[A]], align 8
|
||||
// CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
|
||||
// CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8
|
||||
// CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
|
||||
// CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
|
||||
|
||||
// CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
|
||||
// CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
|
||||
// CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
|
||||
// CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
|
||||
// CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
|
||||
// CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
|
||||
takeA(B().a);
|
||||
|
||||
// CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
|
||||
// CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
|
||||
// CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
|
||||
// CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
|
||||
A x = B().a;
|
||||
|
||||
// CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
|
||||
// CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
|
||||
// CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
|
||||
// CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
|
||||
return B().a;
|
||||
|
||||
// CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче