[MS] Don't reference deleted copy ctors from catchable types
authorReid Kleckner <rnk@google.com>
Wed, 30 Oct 2019 21:38:11 +0000 (14:38 -0700)
committerReid Kleckner <rnk@google.com>
Wed, 30 Oct 2019 22:06:26 +0000 (15:06 -0700)
When throwing objects with deleted copy constructors, the copy ctor
field of the catchable type should remain null and the mangle name
changes. This already worked in simple cases, but in cases involving
non-trivial subobjects, sometimes LookupCopyingConstructor could return
a non-null but deleted constructor decl. Skip those and don't reference
them.

Fixes PR43680

clang/lib/Sema/SemaExprCXX.cpp
clang/test/CodeGenCXX/microsoft-abi-throw.cpp

index 4fdd15b..67492a2 100644 (file)
@@ -921,7 +921,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
       // cannot be a simple walk of the class's decls.  Instead, we must perform
       // lookup and overload resolution.
       CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0);
-      if (!CD)
+      if (!CD || CD->isDeleted())
         continue;
 
       // Mark the constructor referenced as it is used by this throw expression.
index f55b94a..937f2da 100644 (file)
@@ -14,6 +14,8 @@
 // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat
 // CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"??_DY@@QAEXXZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0?AUDeletedCopy@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor17* @"??_R0?AUDeletedCopy@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat
+// CHECk-DAG: @"_CT??_R0?AUMoveOnly@@@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"??_R0?AUMoveOnly@@@8" to i8*), i32 0, i321-1, i32 0, i32 4, i8* null }, section ".xdata", comda
 // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CTA2$$T" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0$$T@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
@@ -71,6 +73,31 @@ void h(Default &d) {
   throw d;
 }
 
+struct DeletedCopy {
+  DeletedCopy();
+  DeletedCopy(DeletedCopy &&);
+  DeletedCopy(const DeletedCopy &) = delete;
+};
+void throwDeletedCopy() { throw DeletedCopy(); }
+
+
+struct MoveOnly {
+  MoveOnly();
+  MoveOnly(MoveOnly &&);
+  ~MoveOnly();
+  MoveOnly(const MoveOnly &) = delete;
+
+  // For some reason this subobject was important for reproducing PR43680
+  struct HasCopy {
+    HasCopy();
+    HasCopy(const HasCopy &o);
+    ~HasCopy();
+    int x;
+  } sub;
+};
+
+void throwMoveOnly() { throw MoveOnly(); }
+
 struct Variadic {
   Variadic(Variadic &, ...);
 };