[cfe-commits] r167920 - in /cfe/trunk: lib/AST/DeclCXX.cpp test/CodeGenCXX/cxx11-special-members.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Nov 13 23:36:28 PST 2012


Author: rsmith
Date: Wed Nov 14 01:36:28 2012
New Revision: 167920

URL: http://llvm.org/viewvc/llvm-project?rev=167920&view=rev
Log:
PR14279: Work around this major miscompilation by treating move operations as
non-trivial if they would not call a move operation, even if they would in fact
call a trivial copy operation. A proper fix is to follow, but this small
directed fix is intended for porting to the 3.2 release branch.

Added:
    cfe/trunk/test/CodeGenCXX/cxx11-special-members.cpp
Modified:
    cfe/trunk/lib/AST/DeclCXX.cpp

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=167920&r1=167919&r2=167920&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Nov 14 01:36:28 2012
@@ -240,10 +240,13 @@
       //    -- the constructor selected to copy/move each direct base class
       //       subobject is trivial, and
       // FIXME: C++0x: We need to only consider the selected constructor
-      // instead of all of them.
+      // instead of all of them. For now, we treat a move constructor as being
+      // non-trivial if it calls anything other than a trivial move constructor.
       if (!BaseClassDecl->hasTrivialCopyConstructor())
         data().HasTrivialCopyConstructor = false;
-      if (!BaseClassDecl->hasTrivialMoveConstructor())
+      if (!BaseClassDecl->hasTrivialMoveConstructor() ||
+          !(BaseClassDecl->hasDeclaredMoveConstructor() ||
+            BaseClassDecl->needsImplicitMoveConstructor()))
         data().HasTrivialMoveConstructor = false;
 
       // C++0x [class.copy]p27:
@@ -255,7 +258,9 @@
       // of all of them.
       if (!BaseClassDecl->hasTrivialCopyAssignment())
         data().HasTrivialCopyAssignment = false;
-      if (!BaseClassDecl->hasTrivialMoveAssignment())
+      if (!BaseClassDecl->hasTrivialMoveAssignment() ||
+          !(BaseClassDecl->hasDeclaredMoveAssignment() ||
+            BaseClassDecl->needsImplicitMoveAssignment()))
         data().HasTrivialMoveAssignment = false;
 
       // C++11 [class.ctor]p6:
@@ -830,7 +835,9 @@
         // FIXME: C++0x: We don't correctly model 'selected' constructors.
         if (!FieldRec->hasTrivialCopyConstructor())
           data().HasTrivialCopyConstructor = false;
-        if (!FieldRec->hasTrivialMoveConstructor())
+        if (!FieldRec->hasTrivialMoveConstructor() ||
+            !(FieldRec->hasDeclaredMoveConstructor() ||
+              FieldRec->needsImplicitMoveConstructor()))
           data().HasTrivialMoveConstructor = false;
 
         // C++0x [class.copy]p27:
@@ -842,7 +849,9 @@
         // FIXME: C++0x: We don't correctly model 'selected' operators.
         if (!FieldRec->hasTrivialCopyAssignment())
           data().HasTrivialCopyAssignment = false;
-        if (!FieldRec->hasTrivialMoveAssignment())
+        if (!FieldRec->hasTrivialMoveAssignment() ||
+            !(FieldRec->hasDeclaredMoveAssignment() ||
+              FieldRec->needsImplicitMoveAssignment()))
           data().HasTrivialMoveAssignment = false;
 
         if (!FieldRec->hasTrivialDestructor())

Added: cfe/trunk/test/CodeGenCXX/cxx11-special-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-special-members.cpp?rev=167920&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx11-special-members.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/cxx11-special-members.cpp Wed Nov 14 01:36:28 2012
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i686-linux-gnu | FileCheck %s
+
+struct A {
+  A(const A&);
+  A &operator=(const A&);
+};
+
+struct B {
+  A a;
+  B(B&&) = default;
+  B &operator=(B&&) = default;
+};
+
+// CHECK: define {{.*}} @_Z2f1
+void f1(B &x) {
+  // CHECK-NOT: memcpy
+  // CHECK: call {{.*}} @_ZN1BC1EOS_(
+  B b(static_cast<B&&>(x));
+}
+
+// CHECK: define {{.*}} @_Z2f2
+void f2(B &x, B &y) {
+  // CHECK-NOT: memcpy
+  // CHECK: call {{.*}} @_ZN1BaSEOS_(
+  x = static_cast<B&&>(y);
+}
+
+// CHECK: define {{.*}} @_ZN1BaSEOS_(
+// CHECK: call {{.*}} @_ZN1AaSERKS_(
+
+// CHECK: define {{.*}} @_ZN1BC2EOS_(
+// CHECK: call {{.*}} @_ZN1AC1ERKS_(





More information about the cfe-commits mailing list