diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index bfe00ea158ac..4980aad1b383 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1541,4 +1541,6 @@ CodeGenFunction::CleanupBlock::~CleanupBlock() { CGF.Builder.restoreIP(SavedIP); } -void EHScopeStack::LazyCleanup::_anchor() {} +EHScopeStack::LazyCleanup::~LazyCleanup() { + llvm_unreachable("LazyCleanup is indestructable"); +} diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 90a5421c6955..5ee3db08eea0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -125,18 +125,23 @@ public: } }; - /// A lazy cleanup. These will be allocated on the cleanup stack - /// and so must be trivially copyable. We "enforce" this by - /// providing no virtual destructor so that subclasses will be - /// encouraged to contain no non-POD types. + /// A lazy cleanup. Subclasses must be POD-like: cleanups will + /// not be destructed, and they will be allocated on the cleanup + /// stack and freely copied and moved around. /// /// LazyCleanup implementations should generally be declared in an /// anonymous namespace. class LazyCleanup { - // Anchor the construction vtable. - virtual void _anchor(); - public: + // Anchor the construction vtable. We use the destructor because + // gcc gives an obnoxious warning if there are virtual methods + // with an accessible non-virtual destructor. Unfortunately, + // declaring this destructor makes it non-trivial, but there + // doesn't seem to be any other way around this warning. + // + // This destructor will never be called. + virtual ~LazyCleanup(); + /// Emit the cleanup. For normal cleanups, this is run in the /// same EH context as when the cleanup was pushed, i.e. the /// immediately-enclosing context of the cleanup scope. For