[cfe-commits] r107411 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/CXX/special/class.copy/p9.cpp

Douglas Gregor dgregor at apple.com
Thu Jul 1 11:27:03 PDT 2010


Author: dgregor
Date: Thu Jul  1 13:27:03 2010
New Revision: 107411

URL: http://llvm.org/viewvc/llvm-project?rev=107411&view=rev
Log:
Teach DeclareImplicitCopyConstructor how to cope with virtual bases
and multi-dimensional array fields. Fixes several bugs found by
inspection.

Added:
    cfe/trunk/test/CXX/special/class.copy/p9.cpp   (with props)
Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=107411&r1=107410&r2=107411&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jul  1 13:27:03 2010
@@ -4915,8 +4915,6 @@
   //   If the class definition does not explicitly declare a copy
   //   constructor, one is declared implicitly.
   
-  // FIXME: virtual bases!
-  
   // C++ [class.copy]p5:
   //   The implicitly-declared copy constructor for a class X will
   //   have the form
@@ -4933,6 +4931,20 @@
                                        BaseEnd = ClassDecl->bases_end();
        HasConstCopyConstructor && Base != BaseEnd; 
        ++Base) {
+    // Virtual bases are handled below.
+    if (Base->isVirtual())
+      continue;
+    
+    const CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    HasConstCopyConstructor
+      = BaseClassDecl->hasConstCopyConstructor(Context);
+  }
+
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                       BaseEnd = ClassDecl->vbases_end();
+       HasConstCopyConstructor && Base != BaseEnd; 
+       ++Base) {
     const CXXRecordDecl *BaseClassDecl
       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
     HasConstCopyConstructor
@@ -4947,14 +4959,12 @@
                                   FieldEnd = ClassDecl->field_end();
        HasConstCopyConstructor && Field != FieldEnd;
        ++Field) {
-    QualType FieldType = (*Field)->getType();
-    if (const ArrayType *Array = Context.getAsArrayType(FieldType))
-      FieldType = Array->getElementType();
+    QualType FieldType = Context.getBaseElementType((*Field)->getType());
     if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
       const CXXRecordDecl *FieldClassDecl
-      = cast<CXXRecordDecl>(FieldClassType->getDecl());
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
       HasConstCopyConstructor
-      = FieldClassDecl->hasConstCopyConstructor(Context);
+        = FieldClassDecl->hasConstCopyConstructor(Context);
     }
   }
   

Added: cfe/trunk/test/CXX/special/class.copy/p9.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p9.cpp?rev=107411&view=auto
==============================================================================
--- cfe/trunk/test/CXX/special/class.copy/p9.cpp (added)
+++ cfe/trunk/test/CXX/special/class.copy/p9.cpp Thu Jul  1 13:27:03 2010
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct ConstCopy {
+  ConstCopy();
+  ConstCopy(const ConstCopy&);
+};
+
+struct NonConstCopy {
+  NonConstCopy();
+  NonConstCopy(NonConstCopy&);
+};
+
+struct VirtualInheritsNonConstCopy : virtual NonConstCopy { 
+  VirtualInheritsNonConstCopy();
+  VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&);
+};
+
+struct ImplicitNonConstCopy1 : NonConstCopy { 
+  ImplicitNonConstCopy1();
+};
+
+struct ImplicitNonConstCopy2 {
+  ImplicitNonConstCopy2();
+  NonConstCopy ncc;
+};
+
+struct ImplicitNonConstCopy3 { 
+  ImplicitNonConstCopy3();
+  NonConstCopy ncc_array[2][3];
+};
+
+struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { 
+  ImplicitNonConstCopy4();
+};
+
+void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1,
+                         const ImplicitNonConstCopy2 &cincc2,
+                         const ImplicitNonConstCopy3 &cincc3,
+                         const ImplicitNonConstCopy4 &cincc4) {
+  (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy1 const' to 'ImplicitNonConstCopy1' is not allowed}}
+  (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy2 const' to 'ImplicitNonConstCopy2' is not allowed}}
+  (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy3 const' to 'ImplicitNonConstCopy3' is not allowed}}
+  (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy4 const' to 'ImplicitNonConstCopy4' is not allowed}}
+}

Propchange: cfe/trunk/test/CXX/special/class.copy/p9.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/special/class.copy/p9.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/special/class.copy/p9.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list