зеркало из https://github.com/microsoft/clang-1.git
Use CXXTemporaryObjectExpr for explicitly-constructed temporaries. We
used to do this, but it got lost when we switched functional-style cast syntax over to using the new initialization code. Fixes PR6457. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97568 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a1359ba1a5
Коммит
91be6f5ccb
|
@ -3439,10 +3439,25 @@ InitializationSequence::Perform(Sema &S,
|
|||
return S.ExprError();
|
||||
|
||||
// Build the an expression that constructs a temporary.
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
|
||||
Constructor,
|
||||
move_arg(ConstructorArgs),
|
||||
ConstructorInitRequiresZeroInit,
|
||||
if (Entity.getKind() == InitializedEntity::EK_Temporary &&
|
||||
(Kind.getKind() == InitializationKind::IK_Direct ||
|
||||
Kind.getKind() == InitializationKind::IK_Value)) {
|
||||
// An explicitly-constructed temporary, e.g., X(1, 2).
|
||||
unsigned NumExprs = ConstructorArgs.size();
|
||||
Expr **Exprs = (Expr **)ConstructorArgs.take();
|
||||
S.MarkDeclarationReferenced(Kind.getLocation(), Constructor);
|
||||
CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
|
||||
Constructor,
|
||||
Entity.getType(),
|
||||
Kind.getLocation(),
|
||||
Exprs,
|
||||
NumExprs,
|
||||
Kind.getParenRange().getEnd()));
|
||||
} else
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
|
||||
Constructor,
|
||||
move_arg(ConstructorArgs),
|
||||
ConstructorInitRequiresZeroInit,
|
||||
Entity.getKind() == InitializedEntity::EK_Base);
|
||||
if (CurInit.isInvalid())
|
||||
return S.ExprError();
|
||||
|
|
|
@ -5051,6 +5051,11 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
|
|||
for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
|
||||
ArgEnd = E->arg_end();
|
||||
Arg != ArgEnd; ++Arg) {
|
||||
if (getDerived().DropCallArgument(*Arg)) {
|
||||
ArgumentChanged = true;
|
||||
break;
|
||||
}
|
||||
|
||||
OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
|
||||
if (TransArg.isInvalid())
|
||||
return SemaRef.ExprError();
|
||||
|
@ -5062,8 +5067,11 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
|
|||
if (!getDerived().AlwaysRebuild() &&
|
||||
T == E->getType() &&
|
||||
Constructor == E->getConstructor() &&
|
||||
!ArgumentChanged)
|
||||
!ArgumentChanged) {
|
||||
// FIXME: Instantiation-specific
|
||||
SemaRef.MarkDeclarationReferenced(E->getTypeBeginLoc(), Constructor);
|
||||
return SemaRef.Owned(E->Retain());
|
||||
}
|
||||
|
||||
// FIXME: Bogus location information
|
||||
SourceLocation CommaLoc;
|
||||
|
|
|
@ -26,3 +26,14 @@ void test_f1(X0 *x0, int *ip, float *fp, double *dp) {
|
|||
f1(x0, ip, dp); // expected-note{{instantiation}}
|
||||
}
|
||||
|
||||
namespace PR6457 {
|
||||
template <typename T> struct X { explicit X(T* p = 0) { }; };
|
||||
template <typename T> struct Y { Y(int, const T& x); };
|
||||
struct A { };
|
||||
template <typename T>
|
||||
struct B {
|
||||
B() : y(0, X<A>()) { }
|
||||
Y<X<A> > y;
|
||||
};
|
||||
B<int> b;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче