diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2024-11-04 08:15:21 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2024-11-13 13:08:16 +0100 |
commit | fb745b54d223acc480a1f024c42806eadd0c5708 (patch) | |
tree | 657fa87768b7c1850a5432d5ec8589c85b2dafbb /compilerplugins | |
parent | bcee366d82392b02745b0070a312624e7baa29d3 (diff) |
new loplugin:reftotemp
look for places where we are taking a reference (i.e. "&") to a
temporary object, which is misleading.
Change-Id: Id0eb4dce3f1ca559f86e02edcbea3ca17bea8e76
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175978
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Jenkins
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/rangedforcopy.cxx | 4 | ||||
-rw-r--r-- | compilerplugins/clang/reftotemp.cxx | 87 | ||||
-rw-r--r-- | compilerplugins/clang/test/reftotemp.cxx | 25 |
3 files changed, 116 insertions, 0 deletions
diff --git a/compilerplugins/clang/rangedforcopy.cxx b/compilerplugins/clang/rangedforcopy.cxx index 3ad407c358bb..16e7746afdcb 100644 --- a/compilerplugins/clang/rangedforcopy.cxx +++ b/compilerplugins/clang/rangedforcopy.cxx @@ -56,6 +56,10 @@ bool RangedForCopy::VisitCXXForRangeStmt( const CXXForRangeStmt* stmt ) if (!type->isRecordType() || type->isReferenceType() || type->isPointerType()) return true; + if (auto exprWithCleanups = dyn_cast<ExprWithCleanups>(varDecl->getInit())) + if (dyn_cast<CXXBindTemporaryExpr>(exprWithCleanups->getSubExpr()->IgnoreImpCasts())) + return true; + if (loplugin::TypeCheck(type).Class("__bit_const_reference").StdNamespace()) { // With libc++ without _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL, diff --git a/compilerplugins/clang/reftotemp.cxx b/compilerplugins/clang/reftotemp.cxx new file mode 100644 index 000000000000..bd430d74fc6a --- /dev/null +++ b/compilerplugins/clang/reftotemp.cxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef LO_CLANG_SHARED_PLUGINS + +#include <cassert> +#include <stack> + +#include "check.hxx" +#include "plugin.hxx" +#include "config_clang.h" + +/** +look for places where we take a reference (i.e. "&") to a temporary value. + +Which is rather dodgy. + +*/ +namespace +{ +class RefToTemp final : public loplugin::FilteringPlugin<RefToTemp> +{ +public: + explicit RefToTemp(loplugin::InstantiationData const& data) + : FilteringPlugin(data) + { + } + + bool VisitVarDecl(const VarDecl* varDecl) + { + if (ignoreLocation(varDecl)) + return true; + // reference parameters might have a default temporary value, which is ok + if (isa<ParmVarDecl>(varDecl)) + return true; + if (!varDecl->getType()->isReferenceType()) + return true; + if (!varDecl->getInit()) + return true; + if (!isTemporaryValue(varDecl->getInit())) + return true; + report(DiagnosticsEngine::Warning, "taking reference to temporary value", + varDecl->getBeginLoc()) + << varDecl->getSourceRange(); + return true; + } + + bool isTemporaryValue(const Expr* expr) + { + if (dyn_cast<MaterializeTemporaryExpr>(expr)) + return true; + if (auto exprWithCleanups = dyn_cast<ExprWithCleanups>(expr)) + if (dyn_cast_or_null<MaterializeTemporaryExpr>( + exprWithCleanups->getSubExpr()->IgnoreImpCasts())) + return true; + return false; + } + + bool preRun() override + { + if (!compiler.getLangOpts().CPlusPlus) + return false; + return true; + } + +private: + void run() override + { + if (preRun()) + { + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + } +}; + +loplugin::Plugin::Registration<RefToTemp> reftotemp("reftotemp"); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/reftotemp.cxx b/compilerplugins/clang/test/reftotemp.cxx new file mode 100644 index 000000000000..2d5d3fd969f8 --- /dev/null +++ b/compilerplugins/clang/test/reftotemp.cxx @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> + +namespace test1 +{ +OUString getString(); +void f() +{ + // expected-error@+1 {{taking reference to temporary value [loplugin:reftotemp]}} + const OUString& rToTemp = getString(); + (void)rToTemp; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |