forked from OSchip/llvm-project
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:
parent
7cbfa4462f
commit
fa6010b6e4
|
@ -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())
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue