See PR51862. The consumers of the Elidable flag in CXXConstructExpr assume that an elidable construction just goes through a single copy/move construction, so that the source object is immediately passed as an argument and is the same type as the parameter itself. With the implementation of P2266 and after some adjustments to the implementation of P1825, we started (correctly, as per standard) allowing more cases where the copy initialization goes through user defined conversions. With this patch we stop using this flag in NRVO contexts, to preserve code that relies on that assumption. This causes no known functional changes, we just stop firing some asserts in a cople of included test cases. Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D109800
35 lines
833 B
C++
35 lines
833 B
C++
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown-gnu -emit-llvm -O1 -fexperimental-new-pass-manager -o - %s | FileCheck %s
|
|
|
|
template <class T> T test() {
|
|
return T();
|
|
}
|
|
|
|
struct A {
|
|
A();
|
|
A(A &);
|
|
A(int);
|
|
operator int();
|
|
};
|
|
|
|
// FIXME: There should be copy elision here.
|
|
// CHECK-LABEL: define{{.*}} void @_Z4testI1AET_v
|
|
// CHECK: call void @_ZN1AC1Ev
|
|
// CHECK-NEXT: call i32 @_ZN1AcviEv
|
|
// CHECK-NEXT: call void @_ZN1AC1Ei
|
|
// CHECK-NEXT: call void @llvm.lifetime.end
|
|
template A test<A>();
|
|
|
|
struct BSub {};
|
|
struct B : BSub {
|
|
B();
|
|
B(B &);
|
|
B(const BSub &);
|
|
};
|
|
|
|
// FIXME: There should be copy elision here.
|
|
// CHECK-LABEL: define{{.*}} void @_Z4testI1BET_v
|
|
// CHECK: call void @_ZN1BC1Ev
|
|
// CHECK: call void @_ZN1BC1ERK4BSub
|
|
// CHECK-NEXT: call void @llvm.lifetime.end
|
|
template B test<B>();
|