forked from OSchip/llvm-project
Only make a call to a copy constructor elidable if in fact we are
doing a copy. Fixes PR12139. llvm-svn: 152485
This commit is contained in:
parent
eace54fcb4
commit
d2f7007e09
|
@ -8876,6 +8876,25 @@ void Sema::DefineImplicitLambdaToBlockPointerConversion(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Determine whether the given list arguments contains exactly one
|
||||||
|
/// "real" (non-default) argument.
|
||||||
|
static bool hasOneRealArgument(MultiExprArg Args) {
|
||||||
|
switch (Args.size()) {
|
||||||
|
case 0:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!Args.get()[1]->isDefaultArgument())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// fall through
|
||||||
|
case 1:
|
||||||
|
return !Args.get()[0]->isDefaultArgument();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ExprResult
|
ExprResult
|
||||||
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
||||||
CXXConstructorDecl *Constructor,
|
CXXConstructorDecl *Constructor,
|
||||||
|
@ -8897,7 +8916,7 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
||||||
// can be omitted by constructing the temporary object
|
// can be omitted by constructing the temporary object
|
||||||
// directly into the target of the omitted copy/move
|
// directly into the target of the omitted copy/move
|
||||||
if (ConstructKind == CXXConstructExpr::CK_Complete &&
|
if (ConstructKind == CXXConstructExpr::CK_Complete &&
|
||||||
Constructor->isCopyOrMoveConstructor() && ExprArgs.size() >= 1) {
|
Constructor->isCopyOrMoveConstructor() && hasOneRealArgument(ExprArgs)) {
|
||||||
Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
|
Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
|
||||||
Elidable = SubExpr->isTemporaryObject(Context, Constructor->getParent());
|
Elidable = SubExpr->isTemporaryObject(Context, Constructor->getParent());
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,3 +53,25 @@ void f() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PR12139 {
|
||||||
|
struct A {
|
||||||
|
A() : value(1) { }
|
||||||
|
A(A const &, int value = 2) : value(value) { }
|
||||||
|
int value;
|
||||||
|
|
||||||
|
static A makeA() { A a; a.value = 2; return a; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// CHECK: define i32 @_ZN7PR121394testEv
|
||||||
|
int test() {
|
||||||
|
// CHECK: call void @_ZN7PR121391A5makeAEv
|
||||||
|
// CHECK-NEXT: call void @_ZN7PR121391AC1ERKS0_i
|
||||||
|
A a(A::makeA(), 3);
|
||||||
|
// CHECK-NEXT: getelementptr inbounds
|
||||||
|
// CHECK-NEXT: load
|
||||||
|
// CHECK-NEXT: ret i32
|
||||||
|
return a.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue