]> granicus.if.org Git - clang/commitdiff
Bind references to opaque r-values correctly. Add a few test cases
authorJohn McCall <rjmccall@apple.com>
Mon, 21 Feb 2011 05:25:38 +0000 (05:25 +0000)
committerJohn McCall <rjmccall@apple.com>
Mon, 21 Feb 2011 05:25:38 +0000 (05:25 +0000)
for ?: on record types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126113 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGenCXX/conditional-gnu-ext.cpp

index 1b7e7a007ed27d36099f7f8721375234ce18ef3e..5d69aad42fff563e01ae205ed092faa92f58300c 100644 (file)
@@ -260,6 +260,10 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
         }
       }
 
+      if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E))
+        if (opaque->getType()->isRecordType())
+          return CGF.EmitOpaqueValueLValue(opaque).getAddress();
+
       // Nothing changed.
       break;
     }
index fea83645a5cfe3f6d15de5eb58a9a99eeb30153a..46c5e7fab6de7f6419116fb4f1baf4735ad24501 100644 (file)
@@ -60,3 +60,83 @@ int main() {
   return  global-2;
 }
 }
+
+namespace test3 {
+  struct A {
+    A();
+    A(const A&);
+    ~A();
+  };
+
+  struct B {
+    B();
+    B(const B&);
+    ~B();
+    operator bool();
+    operator A();
+  };
+
+  B test0(B &x) {
+    // CHECK:    define void @_ZN5test35test0ERNS_1BE(
+    // CHECK:      [[X:%.*]] = alloca [[B:%.*]]*,
+    // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]]
+    // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]]
+    // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
+    // CHECK-NEXT: br i1 [[BOOL]]
+    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[T0]])
+    // CHECK-NEXT: br label
+    // CHECK:      call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
+    // CHECK-NEXT: br label
+    // CHECK:      ret void
+    return x ?: B();
+  }
+
+  B test1() {
+    // CHECK:    define void @_ZN5test35test1Ev(
+    // CHECK:      [[TEMP:%.*]] = alloca [[B]],
+    // CHECK-NEXT: call  void @_ZN5test312test1_helperEv([[B]]* sret [[TEMP]])
+    // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
+    // CHECK-NEXT: br i1 [[BOOL]]
+    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[TEMP]])
+    // CHECK-NEXT: br label
+    // CHECK:      call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
+    // CHECK-NEXT: br label
+    // CHECK:      call void @_ZN5test31BD1Ev([[B]]* [[TEMP]])
+    // CHECK-NEXT: ret void
+    extern B test1_helper();
+    return test1_helper() ?: B();
+  }
+
+
+  A test2(B &x) {
+    // CHECK:    define void @_ZN5test35test2ERNS_1BE(
+    // CHECK:      [[X:%.*]] = alloca [[B]]*,
+    // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]]
+    // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]]
+    // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
+    // CHECK-NEXT: br i1 [[BOOL]]
+    // CHECK:      call void @_ZN5test31BcvNS_1AEEv([[A:%.*]]* sret [[RESULT:%.*]], [[B]]* [[T0]])
+    // CHECK-NEXT: br label
+    // CHECK:      call void @_ZN5test31AC1Ev([[A]]* [[RESULT]])
+    // CHECK-NEXT: br label
+    // CHECK:      ret void
+    return x ?: A();
+  }
+
+  A test3() {
+    // CHECK:    define void @_ZN5test35test3Ev(
+    // CHECK:      [[TEMP:%.*]] = alloca [[B]],
+    // CHECK-NEXT: call  void @_ZN5test312test3_helperEv([[B]]* sret [[TEMP]])
+    // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
+    // CHECK-NEXT: br i1 [[BOOL]]
+    // CHECK:      call void @_ZN5test31BcvNS_1AEEv([[A]]* sret [[RESULT:%.*]], [[B]]* [[TEMP]])
+    // CHECK-NEXT: br label
+    // CHECK:      call void @_ZN5test31AC1Ev([[A]]* [[RESULT]])
+    // CHECK-NEXT: br label
+    // CHECK:      call void @_ZN5test31BD1Ev([[B]]* [[TEMP]])
+    // CHECK-NEXT: ret void
+    extern B test3_helper();
+    return test3_helper() ?: A();
+  }
+
+}