summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-18 20:53:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-18 20:53:32 +0000
commit0b6b8e490c1a81a607bde6e4e92a8a5306c080ce (patch)
treec36575407079ea2d9c35a61b3a74dc0127c5794a /clang/lib/Sema
parente98d63a823f02aa920e9cd4889c303f8e2ad7592 (diff)
downloadbcm5719-llvm-0b6b8e490c1a81a607bde6e4e92a8a5306c080ce.tar.gz
bcm5719-llvm-0b6b8e490c1a81a607bde6e4e92a8a5306c080ce.zip
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
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c727e88adb8..3f1fabcaa35 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8095,11 +8095,17 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
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();
OpenPOWER on IntegriCloud