vsapsai created this revision.
vsapsai added reviewers: rsmith, rjmccall.
Herald added subscribers: dexonsmith, jkorous.

Fixes assertion

> Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible 
> type!"), function cast, file llvm/Support/Casting.h, line 255.

It was triggered by trying to cast `FunctionDecl` to `CXXMethodDecl` as
`CGF.CurCodeDecl` in `CallBaseDtor::Emit`. It was happening because
cleanups were emitted in `ScalarExprEmitter::VisitExprWithCleanups`
after destroying `InlinedInheritingConstructorScope`, so
`CodeGenFunction.CurCodeDecl` didn't correspond to expected cleanup decl.

Fix the assertion by emitting cleanups before leaving
`InlinedInheritingConstructorScope` and changing `CurCodeDecl`.

rdar://problem/45805151


https://reviews.llvm.org/D55543

Files:
  clang/lib/CodeGen/CGClass.cpp
  clang/test/CodeGenCXX/throw-expressions.cpp


Index: clang/test/CodeGenCXX/throw-expressions.cpp
===================================================================
--- clang/test/CodeGenCXX/throw-expressions.cpp
+++ clang/test/CodeGenCXX/throw-expressions.cpp
@@ -112,3 +112,20 @@
   // CHECK: ret i32* @val
   return cond ? val : ((throw "foo"));
 }
+
+// Test throwing object with inlined inherited constructor and non-trivial 
cleanup.
+namespace rdar45805151 {
+  struct BaseException {
+    // Use variadic args to force inlining the inherited constructor.
+    BaseException(const char *format, ...) {}
+    // Add explicit destructor to make it non-trivial.
+    ~BaseException() {}
+  };
+  struct BadException : public BaseException {
+    using BaseException::BaseException;
+  };
+
+  void test9() {
+    throw BadException("foo");
+  }
+}
Index: clang/lib/CodeGen/CGClass.cpp
===================================================================
--- clang/lib/CodeGen/CGClass.cpp
+++ clang/lib/CodeGen/CGClass.cpp
@@ -2196,6 +2196,7 @@
   GlobalDecl GD(Ctor, CtorType);
   InlinedInheritingConstructorScope Scope(*this, GD);
   ApplyInlineDebugLocation DebugScope(*this, GD);
+  RunCleanupsScope RunCleanups(*this);
 
   // Save the arguments to be passed to the inherited constructor.
   CXXInheritedCtorInitExprArgs = Args;


Index: clang/test/CodeGenCXX/throw-expressions.cpp
===================================================================
--- clang/test/CodeGenCXX/throw-expressions.cpp
+++ clang/test/CodeGenCXX/throw-expressions.cpp
@@ -112,3 +112,20 @@
   // CHECK: ret i32* @val
   return cond ? val : ((throw "foo"));
 }
+
+// Test throwing object with inlined inherited constructor and non-trivial cleanup.
+namespace rdar45805151 {
+  struct BaseException {
+    // Use variadic args to force inlining the inherited constructor.
+    BaseException(const char *format, ...) {}
+    // Add explicit destructor to make it non-trivial.
+    ~BaseException() {}
+  };
+  struct BadException : public BaseException {
+    using BaseException::BaseException;
+  };
+
+  void test9() {
+    throw BadException("foo");
+  }
+}
Index: clang/lib/CodeGen/CGClass.cpp
===================================================================
--- clang/lib/CodeGen/CGClass.cpp
+++ clang/lib/CodeGen/CGClass.cpp
@@ -2196,6 +2196,7 @@
   GlobalDecl GD(Ctor, CtorType);
   InlinedInheritingConstructorScope Scope(*this, GD);
   ApplyInlineDebugLocation DebugScope(*this, GD);
+  RunCleanupsScope RunCleanups(*this);
 
   // Save the arguments to be passed to the inherited constructor.
   CXXInheritedCtorInitExprArgs = Args;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to