When a conditional operator is an rvalue of class type, we need to

create a temporary copy of both the "true" and "false" results. Fixes
the Boost.Interprocess failures.

Daniel did all the hard work of tracking down the issue, I get to type
up the trivial fix for this horrible miscompile.

llvm-svn: 104184
This commit is contained in:
Douglas Gregor 2010-05-19 23:40:50 +00:00
parent 7cbfa4462f
commit fa6010b6e4
2 changed files with 45 additions and 2 deletions

View File

@ -2265,9 +2265,32 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// After those conversions, one of the following shall hold:
// -- The second and third operands have the same type; the result
// is of that type.
if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy))
// is of that type. If the operands have class type, the result
// is a prvalue temporary of the result type, which is
// copy-initialized from either the second operand or the third
// operand depending on the value of the first operand.
if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) {
if (LTy->isRecordType()) {
// The operands have class type. Make a temporary copy.
InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
OwningExprResult LHSCopy = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(LHS));
if (LHSCopy.isInvalid())
return QualType();
OwningExprResult RHSCopy = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(RHS));
if (RHSCopy.isInvalid())
return QualType();
LHS = LHSCopy.takeAs<Expr>();
RHS = RHSCopy.takeAs<Expr>();
}
return LTy;
}
// Extension: conditional operator involving vector types.
if (LTy->isVectorType() || RTy->isVectorType())

View File

@ -255,3 +255,23 @@ namespace test1 {
foo(a ? a->x() : 0);
}
}
namespace rdar7998817 {
class X {
X(X&); // expected-note{{declared private here}}
struct ref { };
public:
X();
X(ref);
operator ref();
};
void f(bool B) {
X x;
(void)(B? x // expected-error{{calling a private constructor of class 'rdar7998817::X'}}
: X());
}
}