forked from OSchip/llvm-project
Fix wrong-code bug: __imag on a scalar lvalue should produce a zero rvalue,
rather than an lvalue referring to the scalar. llvm-svn: 150889
This commit is contained in:
parent
e98d63a823
commit
0b6b8e490c
|
@ -1465,9 +1465,10 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
|
||||||
assert(LV.isSimple() && "real/imag on non-ordinary l-value");
|
assert(LV.isSimple() && "real/imag on non-ordinary l-value");
|
||||||
llvm::Value *Addr = LV.getAddress();
|
llvm::Value *Addr = LV.getAddress();
|
||||||
|
|
||||||
// real and imag are valid on scalars. This is a faster way of
|
// __real is valid on scalars. This is a faster way of testing that.
|
||||||
// testing that.
|
// __imag can only produce an rvalue on scalars.
|
||||||
if (!cast<llvm::PointerType>(Addr->getType())
|
if (E->getOpcode() == UO_Real &&
|
||||||
|
!cast<llvm::PointerType>(Addr->getType())
|
||||||
->getElementType()->isStructTy()) {
|
->getElementType()->isStructTy()) {
|
||||||
assert(E->getSubExpr()->getType()->isArithmeticType());
|
assert(E->getSubExpr()->getType()->isArithmeticType());
|
||||||
return LV;
|
return LV;
|
||||||
|
|
|
@ -1642,7 +1642,10 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
|
||||||
|
|
||||||
// __imag on a scalar returns zero. Emit the subexpr to ensure side
|
// __imag on a scalar returns zero. Emit the subexpr to ensure side
|
||||||
// effects are evaluated, but not the actual value.
|
// effects are evaluated, but not the actual value.
|
||||||
CGF.EmitScalarExpr(Op, true);
|
if (Op->isGLValue())
|
||||||
|
CGF.EmitLValue(Op);
|
||||||
|
else
|
||||||
|
CGF.EmitScalarExpr(Op, true);
|
||||||
return llvm::Constant::getNullValue(ConvertType(E->getType()));
|
return llvm::Constant::getNullValue(ConvertType(E->getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8095,11 +8095,17 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
|
||||||
case UO_Real:
|
case UO_Real:
|
||||||
case UO_Imag:
|
case UO_Imag:
|
||||||
resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real);
|
resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real);
|
||||||
// _Real and _Imag map ordinary l-values into ordinary l-values.
|
// _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary
|
||||||
|
// complex l-values to ordinary l-values and all other values to r-values.
|
||||||
if (Input.isInvalid()) return ExprError();
|
if (Input.isInvalid()) return ExprError();
|
||||||
if (Input.get()->getValueKind() != VK_RValue &&
|
if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) {
|
||||||
Input.get()->getObjectKind() == OK_Ordinary)
|
if (Input.get()->getValueKind() != VK_RValue &&
|
||||||
VK = Input.get()->getValueKind();
|
Input.get()->getObjectKind() == OK_Ordinary)
|
||||||
|
VK = Input.get()->getValueKind();
|
||||||
|
} else if (!getLangOptions().CPlusPlus) {
|
||||||
|
// In C, a volatile scalar is read by __imag. In C++, it is not.
|
||||||
|
Input = DefaultLvalueConversion(Input.take());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case UO_Extension:
|
case UO_Extension:
|
||||||
resultType = Input.get()->getType();
|
resultType = Input.get()->getType();
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
// RUN: %clang_cc1 -verify %s
|
||||||
|
|
||||||
|
void f1() {
|
||||||
|
int a = 1;
|
||||||
|
int b = __imag a;
|
||||||
|
int *c = &__real a;
|
||||||
|
int *d = &__imag a; // expected-error {{must be an lvalue}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2() {
|
||||||
|
_Complex int a = 1;
|
||||||
|
int b = __imag a;
|
||||||
|
int *c = &__real a;
|
||||||
|
int *d = &__imag a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f3() {
|
||||||
|
double a = 1;
|
||||||
|
double b = __imag a;
|
||||||
|
double *c = &__real a;
|
||||||
|
double *d = &__imag a; // expected-error {{must be an lvalue}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f4() {
|
||||||
|
_Complex double a = 1;
|
||||||
|
double b = __imag a;
|
||||||
|
double *c = &__real a;
|
||||||
|
double *d = &__imag a;
|
||||||
|
}
|
Loading…
Reference in New Issue