[cfe-commits] r145269 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/CXX/special/class.copy/p15-0x.cpp test/CXX/special/class.copy/p15-inclass.cpp

Douglas Gregor dgregor at apple.com
Mon Nov 28 12:03:15 PST 2011


Author: dgregor
Date: Mon Nov 28 14:03:15 2011
New Revision: 145269

URL: http://llvm.org/viewvc/llvm-project?rev=145269&view=rev
Log:
When synthesizing an implicitly-defined copy or move constructor, or
when computing the exception specification of a copy or move constructor,
ignore non-static data member initializers. Fixes PR11418 /
<rdar://problem/10478642>.

Added:
    cfe/trunk/test/CXX/special/class.copy/p15-inclass.cpp
Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/special/class.copy/p15-0x.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=145269&r1=145268&r2=145269&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 28 14:03:15 2011
@@ -2633,6 +2633,19 @@
     else
       IIK = IIK_Default;
   }
+  
+  bool isImplicitCopyOrMove() const {
+    switch (IIK) {
+    case IIK_Copy:
+    case IIK_Move:
+      return true;
+      
+    case IIK_Default:
+      return false;
+    }
+    
+    return false;
+  }
 };
 }
 
@@ -2678,7 +2691,7 @@
   // C++0x [class.base.init]p8: if the entity is a non-static data member that
   // has a brace-or-equal-initializer, the entity is initialized as specified
   // in [dcl.init].
-  if (Field->hasInClassInitializer()) {
+  if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) {
     CXXCtorInitializer *Init;
     if (Indirect)
       Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect,
@@ -8583,12 +8596,7 @@
   for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
                                FEnd = ClassDecl->field_end();
        F != FEnd; ++F) {
-    if (F->hasInClassInitializer()) {
-      if (Expr *E = F->getInClassInitializer())
-        ExceptSpec.CalledExpr(E);
-      else if (!F->isInvalidDecl())
-        ExceptSpec.SetDelayed();
-    } else if (const RecordType *RecordTy
+    if (const RecordType *RecordTy
               = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
       CXXConstructorDecl *Constructor = LookupMovingConstructor(FieldRecDecl);

Modified: cfe/trunk/test/CXX/special/class.copy/p15-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p15-0x.cpp?rev=145269&r1=145268&r2=145269&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.copy/p15-0x.cpp (original)
+++ cfe/trunk/test/CXX/special/class.copy/p15-0x.cpp Mon Nov 28 14:03:15 2011
@@ -16,3 +16,26 @@
     bar obj2(obj);
   }
 }
+
+namespace PR11418 {
+  template<typename T>
+  T may_throw() {
+    return T();
+  }
+
+  template<typename T> T &&declval() noexcept;
+
+  struct NonPOD {
+    NonPOD();
+    NonPOD(const NonPOD &) noexcept;
+    NonPOD(NonPOD &&) noexcept;
+  };
+
+  struct X {
+    NonPOD np = may_throw<NonPOD>();
+  };
+
+  static_assert(noexcept(declval<X>()), "noexcept isn't working at all");
+  static_assert(noexcept(X(declval<X&>())), "copy constructor can't throw");
+  static_assert(noexcept(X(declval<X>())), "move constructor can't throw");
+}

Added: cfe/trunk/test/CXX/special/class.copy/p15-inclass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p15-inclass.cpp?rev=145269&view=auto
==============================================================================
--- cfe/trunk/test/CXX/special/class.copy/p15-inclass.cpp (added)
+++ cfe/trunk/test/CXX/special/class.copy/p15-inclass.cpp Mon Nov 28 14:03:15 2011
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+namespace PR11418 {
+  struct NonPOD {
+    NonPOD();
+    NonPOD(const NonPOD &);
+    NonPOD(NonPOD &&);
+  };
+
+  struct X {
+    NonPOD np;
+    int a = 17;
+  };
+
+  void check_copy(X x) {
+    X x2(x);
+  }
+
+  void check_move(X x) {
+    X x3(static_cast<X&&>(x));
+  }
+
+  // CHECK: define linkonce_odr void @_ZN7PR114181XC2EOS0_
+  // CHECK-NOT: 17
+  // CHECK: call void @_ZN7PR114186NonPODC1EOS0_
+  // CHECK-NOT: 17
+  // CHECK: load i32* 
+  // CHECK-NOT: 17
+  // CHECK: store i32
+  // CHECK-NOT: 17
+  // CHECK: ret
+
+  // CHECK: define linkonce_odr void @_ZN7PR114181XC2ERKS0_
+  // CHECK-NOT: 17
+  // CHECK: call void @_ZN7PR114186NonPODC1ERKS0_
+  // CHECK-NOT: 17
+  // CHECK: load i32* 
+  // CHECK-NOT: 17
+  // CHECK: store i32
+  // CHECK-NOT: 17
+  // CHECK: ret
+}





More information about the cfe-commits mailing list