[cfe-commits] r114071 - in /cfe/trunk: lib/AST/Expr.cpp test/CodeGenCXX/temporaries.cpp

John McCall rjmccall at apple.com
Wed Sep 15 23:57:56 PDT 2010


Author: rjmccall
Date: Thu Sep 16 01:57:56 2010
New Revision: 114071

URL: http://llvm.org/viewvc/llvm-project?rev=114071&view=rev
Log:
Right, there are *two* cases of pr-value class-type expressions that don't
derive from temporaries of the same type.  Black-list member expressions
as well.


Modified:
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/test/CodeGenCXX/temporaries.cpp

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=114071&r1=114070&r2=114071&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Sep 16 01:57:56 2010
@@ -1659,9 +1659,10 @@
   // Temporaries are by definition pr-values of class type.
   if (!E->Classify(C).isPRValue()) return false;
 
-  // Black-list implicit derived-to-base conversions, which are the
-  // only way we can get a pr-value of class type that doesn't refer
-  // to a temporary of that type.
+  // Black-list a few cases which yield pr-values of class type that don't
+  // refer to temporaries of that type:
+
+  // - implicit derived-to-base conversions
   if (isa<ImplicitCastExpr>(E)) {
     switch (cast<ImplicitCastExpr>(E)->getCastKind()) {
     case CK_DerivedToBase:
@@ -1672,6 +1673,10 @@
     }
   }
 
+  // - member expressions (all)
+  if (isa<MemberExpr>(E))
+    return false;
+
   return true;
 }
 

Modified: cfe/trunk/test/CodeGenCXX/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/temporaries.cpp?rev=114071&r1=114070&r2=114071&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/temporaries.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/temporaries.cpp Thu Sep 16 01:57:56 2010
@@ -344,6 +344,7 @@
 
   void foo();
   A fooA();
+  void takeA(A a);
 
   // CHECK: define void @_ZN7Elision5test0Ev()
   void test0() {
@@ -441,4 +442,37 @@
 
     // CHECK:      call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
   }
+
+  // rdar://problem/8433352
+  // CHECK: define void @_ZN7Elision5test5Ev([[A]]* sret
+  struct B { A a; B(); };
+  A test5() {
+    // CHECK:      [[AT0:%.*]] = alloca [[A]], align 8
+    // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
+    // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8
+    // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
+    // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
+
+    // CHECK:      call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
+    // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
+    // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
+    // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
+    takeA(B().a);
+
+    // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
+    // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
+    A x = B().a;
+
+    // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
+    // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
+    return B().a;
+
+    // CHECK:      call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
+  }
 }





More information about the cfe-commits mailing list