[cfe-commits] r150889 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExpr.cpp test/Sema/complex-imag.c
Richard Smith
richard-llvm at metafoo.co.uk
Sat Feb 18 12:53:33 PST 2012
Author: rsmith
Date: Sat Feb 18 14:53:32 2012
New Revision: 150889
URL: http://llvm.org/viewvc/llvm-project?rev=150889&view=rev
Log:
Fix wrong-code bug: __imag on a scalar lvalue should produce a zero rvalue,
rather than an lvalue referring to the scalar.
Added:
cfe/trunk/test/Sema/complex-imag.c
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=150889&r1=150888&r2=150889&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Feb 18 14:53:32 2012
@@ -1465,9 +1465,10 @@
assert(LV.isSimple() && "real/imag on non-ordinary l-value");
llvm::Value *Addr = LV.getAddress();
- // real and imag are valid on scalars. This is a faster way of
- // testing that.
- if (!cast<llvm::PointerType>(Addr->getType())
+ // __real is valid on scalars. This is a faster way of testing that.
+ // __imag can only produce an rvalue on scalars.
+ if (E->getOpcode() == UO_Real &&
+ !cast<llvm::PointerType>(Addr->getType())
->getElementType()->isStructTy()) {
assert(E->getSubExpr()->getType()->isArithmeticType());
return LV;
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=150889&r1=150888&r2=150889&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sat Feb 18 14:53:32 2012
@@ -1642,7 +1642,10 @@
// __imag on a scalar returns zero. Emit the subexpr to ensure side
// 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()));
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150889&r1=150888&r2=150889&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Feb 18 14:53:32 2012
@@ -8095,11 +8095,17 @@
case UO_Real:
case UO_Imag:
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.get()->getValueKind() != VK_RValue &&
- Input.get()->getObjectKind() == OK_Ordinary)
- VK = Input.get()->getValueKind();
+ if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) {
+ if (Input.get()->getValueKind() != VK_RValue &&
+ 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;
case UO_Extension:
resultType = Input.get()->getType();
Added: cfe/trunk/test/Sema/complex-imag.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/complex-imag.c?rev=150889&view=auto
==============================================================================
--- cfe/trunk/test/Sema/complex-imag.c (added)
+++ cfe/trunk/test/Sema/complex-imag.c Sat Feb 18 14:53:32 2012
@@ -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;
+}
More information about the cfe-commits
mailing list