[cfe-commits] r112019 - in /cfe/trunk: lib/CodeGen/CGExprAgg.cpp test/CodeGenCXX/volatile.cpp
John McCall
rjmccall at apple.com
Tue Aug 24 19:50:31 PDT 2010
Author: rjmccall
Date: Tue Aug 24 21:50:31 2010
New Revision: 112019
URL: http://llvm.org/viewvc/llvm-project?rev=112019&view=rev
Log:
Expression statements undergo lvalue-to-rvalue conversion in C,
but not in C++, so don't emit aggregate loads of volatile references
in null context in C++. Happens to have been caught by an assertion.
We do not get the scalar case right. Volatiles are really broken.
Added:
cfe/trunk/test/CodeGenCXX/volatile.cpp
Modified:
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=112019&r1=112018&r2=112019&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Aug 24 21:50:31 2010
@@ -192,10 +192,18 @@
void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
assert(Src.isAggregate() && "value must be aggregate value!");
- // If the result is ignored, don't copy from the value.
+ // If DestPtr is null, then we're evaluating an aggregate expression
+ // in a context (like an expression statement) that doesn't care
+ // about the result. C says that an lvalue-to-rvalue conversion is
+ // performed in these cases; C++ says that it is not. In either
+ // case, we don't actually need to do anything unless the value is
+ // volatile.
if (DestPtr == 0) {
- if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
+ if (!Src.isVolatileQualified() ||
+ CGF.CGM.getLangOptions().CPlusPlus ||
+ (IgnoreResult && Ignore))
return;
+
// If the source is volatile, we must read from it; to do that, we need
// some place to put it.
DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
Added: cfe/trunk/test/CodeGenCXX/volatile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/volatile.cpp?rev=112019&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/volatile.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/volatile.cpp Tue Aug 24 21:50:31 2010
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// Check that IR gen doesn't try to do an lvalue-to-rvalue conversion
+// on a volatile reference result. rdar://problem/8338198
+namespace test0 {
+ struct A {
+ A(const A& t);
+ A& operator=(const A& t);
+ volatile A& operator=(const volatile A& t) volatile;
+ };
+
+ volatile A *array;
+
+ // CHECK: define void @_ZN5test04testENS_1AE(
+ void test(A t) {
+ // CHECK: [[ARR:%.*]] = load [[A:%.*]]** @_ZN5test05arrayE, align 8
+ // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]]* [[ARR]], i64 0
+ // CHECK-NEXT: [[TMP:%.*]] = call [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* [[T:%.*]])
+ // CHECK-NEXT: ret void
+ array[0] = t;
+ }
+}
+
+namespace test1 {
+ volatile int *x;
+
+ // CHECK: define void @_ZN5test14testEv()
+ void test() {
+ // CHECK: [[TMP:%.*]] = load i32** @_ZN5test11xE, align 8
+ // *** FIXME: no! bad! should not be loaded! ***
+ // CHECK-NEXT: [[TMP1:%.*]] = volatile load i32* [[TMP]]
+ // CHECK-NEXT: ret void
+ *x;
+ }
+}
More information about the cfe-commits
mailing list