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