From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- compilerplugins/clang/dbgunhandledexception.cxx | 128 ++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 compilerplugins/clang/dbgunhandledexception.cxx (limited to 'compilerplugins/clang/dbgunhandledexception.cxx') diff --git a/compilerplugins/clang/dbgunhandledexception.cxx b/compilerplugins/clang/dbgunhandledexception.cxx new file mode 100644 index 000000000..e6c1f157c --- /dev/null +++ b/compilerplugins/clang/dbgunhandledexception.cxx @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * Based on LLVM/Clang. + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + */ + +#ifndef LO_CLANG_SHARED_PLUGINS + +#include "check.hxx" +#include "plugin.hxx" +#include +#include +#include + +namespace loplugin +{ +/* +This is a compile check. + +Check that DBG_UNHANDLED_EXCEPTION is always the first statement in a catch block, otherwise +it does not work properly. +*/ + +class DbgUnhandledException : public loplugin::FilteringPlugin +{ +public: + explicit DbgUnhandledException(InstantiationData const& data); + virtual void run() override; + bool VisitCallExpr(CallExpr const* call); + bool TraverseCXXCatchStmt(CXXCatchStmt*); + bool PreTraverseCXXCatchStmt(CXXCatchStmt*); + bool PostTraverseCXXCatchStmt(CXXCatchStmt*, bool traverseOk); + +private: + std::stack currCatchStmt; +}; + +DbgUnhandledException::DbgUnhandledException(const InstantiationData& data) + : FilteringPlugin(data) +{ +} + +void DbgUnhandledException::run() +{ + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); +} + +bool DbgUnhandledException::PreTraverseCXXCatchStmt(CXXCatchStmt* catchStmt) +{ + currCatchStmt.push(catchStmt); + return true; +} + +bool DbgUnhandledException::PostTraverseCXXCatchStmt(CXXCatchStmt* catchStmt, bool) +{ + assert(currCatchStmt.top() == catchStmt); + (void)catchStmt; + currCatchStmt.pop(); + return true; +} + +bool DbgUnhandledException::TraverseCXXCatchStmt(CXXCatchStmt* catchStmt) +{ + if (!PreTraverseCXXCatchStmt(catchStmt)) + return false; + bool ret = RecursiveASTVisitor::TraverseCXXCatchStmt(catchStmt); + if (!PostTraverseCXXCatchStmt(catchStmt, ret)) + return false; + return ret; +} + +bool DbgUnhandledException::VisitCallExpr(const CallExpr* call) +{ + if (ignoreLocation(call)) + return true; + const FunctionDecl* func = call->getDirectCallee(); + if (!func) + return true; + + if (!func->getIdentifier() || func->getName() != "DbgUnhandledException") + return true; + + if (currCatchStmt.empty()) + { + report(DiagnosticsEngine::Warning, "DBG_UNHANDLED_EXCEPTION outside catch block", + call->getBeginLoc()); + return true; + } + auto catchBlock = dyn_cast(currCatchStmt.top()->getHandlerBlock()); + if (!catchBlock) + { + report(DiagnosticsEngine::Warning, + "something wrong with DBG_UNHANDLED_EXCEPTION, no CompoundStmt?", + call->getBeginLoc()); + return true; + } + if (catchBlock->size() < 1) + { + report(DiagnosticsEngine::Warning, + "something wrong with DBG_UNHANDLED_EXCEPTION, CompoundStmt size == 0?", + call->getBeginLoc()); + return true; + } + + Stmt const* firstStmt = *catchBlock->body_begin(); + if (auto exprWithCleanups = dyn_cast(firstStmt)) + firstStmt = exprWithCleanups->getSubExpr(); + if (firstStmt != call) + { + report(DiagnosticsEngine::Warning, + "DBG_UNHANDLED_EXCEPTION must be first statement in catch block", + call->getBeginLoc()); + } + return true; +} + +static Plugin::Registration dbgunhandledexception("dbgunhandledexception"); + +} // namespace + +#endif // LO_CLANG_SHARED_PLUGINS + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3