diff options
52 files changed, 331 insertions, 48 deletions
diff --git a/canvas/source/cairo/cairo_repainttarget.hxx b/canvas/source/cairo/cairo_repainttarget.hxx index 558ec7921ecb..94d3d3845b3e 100644 --- a/canvas/source/cairo/cairo_repainttarget.hxx +++ b/canvas/source/cairo/cairo_repainttarget.hxx @@ -33,7 +33,7 @@ namespace cairocanvas This interface must be implemented on all canvas implementations that hand out XCachedPrimitives */ - class RepaintTarget + class SAL_LOPLUGIN_ANNOTATE("crosscast") RepaintTarget { public: virtual ~RepaintTarget() {} diff --git a/canvas/source/cairo/cairo_surfaceprovider.hxx b/canvas/source/cairo/cairo_surfaceprovider.hxx index a5115a507863..1ff6f2aa7d3f 100644 --- a/canvas/source/cairo/cairo_surfaceprovider.hxx +++ b/canvas/source/cairo/cairo_surfaceprovider.hxx @@ -37,7 +37,7 @@ namespace cairocanvas This interface must be implemented on all canvas implementations that hand out XCachedPrimitives */ - class SurfaceProvider : public css::uno::XInterface + class SAL_LOPLUGIN_ANNOTATE("crosscast") SurfaceProvider : public css::uno::XInterface { public: virtual ~SurfaceProvider() {} diff --git a/canvas/source/vcl/repainttarget.hxx b/canvas/source/vcl/repainttarget.hxx index b7b4058e9e9d..b8bac4ab9210 100644 --- a/canvas/source/vcl/repainttarget.hxx +++ b/canvas/source/vcl/repainttarget.hxx @@ -34,7 +34,7 @@ namespace vclcanvas This interface must be implemented on all canvas implementations that hand out XCachedPrimitives */ - class RepaintTarget + class SAL_LOPLUGIN_ANNOTATE("crosscast") RepaintTarget { public: virtual ~RepaintTarget() {} diff --git a/chart2/inc/ChartModel.hxx b/chart2/inc/ChartModel.hxx index c8dc4b55e969..b877e47db5e0 100644 --- a/chart2/inc/ChartModel.hxx +++ b/chart2/inc/ChartModel.hxx @@ -112,7 +112,8 @@ typedef cppu::WeakImplHelper< class UndoManager; class ChartView; -class OOO_DLLPUBLIC_CHARTTOOLS ChartModel final : public impl::ChartModel_Base, public sfx2::XmlDump +class OOO_DLLPUBLIC_CHARTTOOLS SAL_LOPLUGIN_ANNOTATE("crosscast") ChartModel final : + public impl::ChartModel_Base, public sfx2::XmlDump { private: diff --git a/chart2/source/controller/inc/TabPageNotifiable.hxx b/chart2/source/controller/inc/TabPageNotifiable.hxx index 440cda2de9aa..a5da029810b1 100644 --- a/chart2/source/controller/inc/TabPageNotifiable.hxx +++ b/chart2/source/controller/inc/TabPageNotifiable.hxx @@ -27,7 +27,7 @@ class BuilderPage; namespace chart { -class TabPageNotifiable +class SAL_LOPLUGIN_ANNOTATE("crosscast") TabPageNotifiable { public: virtual void setInvalidPage(BuilderPage* pTabPage) = 0; diff --git a/compilerplugins/clang/crosscast.cxx b/compilerplugins/clang/crosscast.cxx new file mode 100644 index 000000000000..293b8646d152 --- /dev/null +++ b/compilerplugins/clang/crosscast.cxx @@ -0,0 +1,166 @@ +/* -*- 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/. + */ + +// Find uses of dynamic_cast that cast between unrelated classes, which is suspicious and might +// indicate a bug. The heuristic used to consider two classes unrelated is that neither derives +// from the other (directly or indirectly) and they do not both virtually derive (directly or +// indirectly) from a common third class. Additionally, class definitions can be attributed with +// SAL_LOPLUGIN_ANNOTATE("crosscast") (from sal/types.h) to suppress false warnings about known-good +// cases casting from or to such a class. + +#ifndef LO_CLANG_SHARED_PLUGINS + +#include <cassert> +#include <set> + +#include "compat.hxx" +#include "plugin.hxx" + +namespace +{ +void computeVirtualBases(CXXRecordDecl const* decl, std::set<CXXRecordDecl const*>* vbases) +{ + assert(vbases != nullptr); + for (auto const& i : decl->bases()) + { + auto const d = i.getType()->getAsCXXRecordDecl(); + if (d == nullptr) + { + continue; + } + if (i.isVirtual()) + { + if (!vbases->insert(d->getCanonicalDecl()).second) + { + // As we track the already computed virtual bases in vbases anyway, we can cheaply + // optimize the case where we see a virtual base again, even though we don't bother + // to optimize the case where we see a non-virtual base multiple times: + continue; + } + } + computeVirtualBases(d, vbases); + } +} + +bool compareVirtualBases(CXXRecordDecl const* decl, std::set<CXXRecordDecl const*>& vbases) +{ + for (auto const& i : decl->bases()) + { + auto const d = i.getType()->getAsCXXRecordDecl(); + if (d == nullptr) + { + continue; + } + if (i.isVirtual() && vbases.count(d->getCanonicalDecl()) == 1) + { + return true; + } + if (compareVirtualBases(d, vbases)) + { + return true; + } + } + return false; +} + +bool haveCommonVirtualBase(CXXRecordDecl const* decl1, CXXRecordDecl const* decl2) +{ + std::set<CXXRecordDecl const*> vbases; + computeVirtualBases(decl1, &vbases); + return compareVirtualBases(decl2, vbases); +} + +bool isAllowedInCrossCasts(CXXRecordDecl const* decl) +{ + auto const def = decl->getDefinition(); + if (def == nullptr) + { + return false; + } + for (auto const attr : def->specific_attrs<AnnotateAttr>()) + { + if (attr->getAnnotation() == "loplugin:crosscast") + { + return true; + } + } + return false; +} + +class CrossCast final : public loplugin::FilteringPlugin<CrossCast> +{ +public: + explicit CrossCast(loplugin::InstantiationData const& data) + : FilteringPlugin(data) + { + } + + bool preRun() override { return compiler.getLangOpts().CPlusPlus; } + + void run() override + { + if (preRun()) + { + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + } + + bool VisitCXXDynamicCastExpr(CXXDynamicCastExpr const* expr) + { + if (ignoreLocation(expr)) + { + return true; + } + auto const t2 = expr->getTypeAsWritten(); + if (t2->isVoidPointerType()) + { + return true; + } + auto const d2 = t2->getPointeeCXXRecordDecl(); + if (d2 == nullptr) + { + return true; + } + auto const t1 = compat::getSubExprAsWritten(expr)->getType(); + auto t1a = t1; + if (auto const t = t1a->getAs<clang::PointerType>()) + { + t1a = t->getPointeeType(); + } + auto const d1 = t1a->getAsCXXRecordDecl(); + if (d1 == nullptr) + { + return true; + } + if (d1->getCanonicalDecl() == d2->getCanonicalDecl() || d1->isDerivedFrom(d2) + || d2->isDerivedFrom(d1) || haveCommonVirtualBase(d1, d2)) + { + return true; + } + if (isAllowedInCrossCasts(d1) || isAllowedInCrossCasts(d2)) + { + return true; + } + if (suppressWarningAt(expr->getBeginLoc())) + { + return true; + } + report(DiagnosticsEngine::Warning, "suspicious dynamic cross cast from %0 to %1", + expr->getExprLoc()) + << t1 << t2 << expr->getSourceRange(); + return true; + } +}; + +loplugin::Plugin::Registration<CrossCast> crosscast("crosscast"); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/crosscast.cxx b/compilerplugins/clang/test/crosscast.cxx new file mode 100644 index 000000000000..113557337113 --- /dev/null +++ b/compilerplugins/clang/test/crosscast.cxx @@ -0,0 +1,96 @@ +/* -*- 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/. + */ + +struct Base +{ + virtual ~Base(); +}; + +struct Derived : Base +{ +}; + +struct Virtual1 : virtual Base +{ +}; + +struct Virtual2 : virtual Base +{ +}; + +struct Virtual2a : Virtual2 +{ +}; + +struct Other +{ + virtual ~Other(); +}; + +struct[[clang::annotate("loplugin:crosscast")]] Ok { virtual ~Ok(); }; + +Base* up(Derived* p) { return dynamic_cast<Base*>(p); } + +Base& up(Derived& p) { return dynamic_cast<Base&>(p); } + +Derived* down(Base* p) { return dynamic_cast<Derived*>(p); } + +Derived& down(Base& p) { return dynamic_cast<Derived&>(p); } + +Base* self(Base* p) { return dynamic_cast<Base*>(p); } + +Base& self(Base& p) { return dynamic_cast<Base&>(p); } + +Virtual1* crossVirtual(Virtual2a* p) { return dynamic_cast<Virtual1*>(p); } + +Virtual1& crossVirtual(Virtual2a& p) { return dynamic_cast<Virtual1&>(p); } + +Base* crossFromOther(Other* p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Other *' to 'Base *' [loplugin:crosscast]}} + return dynamic_cast<Base*>(p); +} + +Base& crossFromOther(Other& p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Other' to 'Base &' [loplugin:crosscast]}} + return dynamic_cast<Base&>(p); +} + +Other* crossToOther(Base* p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Base *' to 'Other *' [loplugin:crosscast]}} + return dynamic_cast<Other*>(p); +} + +Other& crossToOther(Base& p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Base' to 'Other &' [loplugin:crosscast]}} + return dynamic_cast<Other&>(p); +} + +Base* crossFromOk(Ok* p) { return dynamic_cast<Base*>(p); } + +Base& crossFromOk(Ok& p) { return dynamic_cast<Base&>(p); } + +Ok* crossToOk(Base* p) { return dynamic_cast<Ok*>(p); } + +Ok& crossToOk(Base& p) { return dynamic_cast<Ok&>(p); } + +void* mostDerived(Base* p) { return dynamic_cast<void*>(p); } + +template <typename T> T generic1(Base* p) { return dynamic_cast<T>(p); } + +template <typename T> T* generic2(Base* p) { return dynamic_cast<T*>(p); } + +template <typename T> Derived* generic3(T p) { return dynamic_cast<Derived*>(p); } + +template <typename T> Derived* generic4(T* p) { return dynamic_cast<Derived*>(p); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx b/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx index a78f29fda86e..119ccb3b5f20 100644 --- a/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx +++ b/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx @@ -79,7 +79,7 @@ namespace drawinglayer::primitive2d /* helper for linear and radial gradient, both get derived from this to share common definitions and functionality **/ - class SvgGradientHelper + class SAL_LOPLUGIN_ANNOTATE("crosscast") SvgGradientHelper { private: /// the extra gradient transform diff --git a/include/editeng/unotext.hxx b/include/editeng/unotext.hxx index ece9b13de567..1d6743a0e410 100644 --- a/include/editeng/unotext.hxx +++ b/include/editeng/unotext.hxx @@ -235,7 +235,8 @@ namespace accessibility } -class EDITENG_DLLPUBLIC SvxUnoTextRangeBase : public css::text::XTextRange, +class EDITENG_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") SvxUnoTextRangeBase : + public css::text::XTextRange, public css::beans::XPropertySet, public css::beans::XMultiPropertySet, public css::beans::XMultiPropertyStates, diff --git a/include/embeddedobj/embeddedupdate.hxx b/include/embeddedobj/embeddedupdate.hxx index 1db3f36d61dc..63e7bf4464c8 100644 --- a/include/embeddedobj/embeddedupdate.hxx +++ b/include/embeddedobj/embeddedupdate.hxx @@ -24,7 +24,7 @@ namespace embed @since LibreOffice 7.4 */ -class EMBOBJ_DLLPUBLIC EmbeddedUpdate +class EMBOBJ_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") EmbeddedUpdate { /** By "Refresh all" is used to perform an OLE update and a link update. In the case of a link update, the class OCommonEmbeddedObject is diff --git a/include/oox/core/contexthandler2.hxx b/include/oox/core/contexthandler2.hxx index 9843a40e95d6..1414db7f242d 100644 --- a/include/oox/core/contexthandler2.hxx +++ b/include/oox/core/contexthandler2.hxx @@ -69,7 +69,7 @@ struct ElementInfo; and implEndRecord() functions of this helper. Again, this is implemented already in the classes ContextHandler2 and FragmentHandler2. */ -class OOX_DLLPUBLIC ContextHandler2Helper +class OOX_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") ContextHandler2Helper { public: explicit ContextHandler2Helper( bool bEnableTrimSpace, XmlFilterBase& rFilter ); diff --git a/include/oox/mathml/export.hxx b/include/oox/mathml/export.hxx index e9589a0d1f46..a9f3862867ed 100644 --- a/include/oox/mathml/export.hxx +++ b/include/oox/mathml/export.hxx @@ -23,7 +23,7 @@ namespace oox Interface class, StarMath will implement writeFormula*() to write out markup representing the formula. */ -class OOX_DLLPUBLIC FormulaExportBase +class OOX_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") FormulaExportBase { public: virtual void writeFormulaOoxml(::sax_fastparser::FSHelperPtr pSerializer, diff --git a/include/oox/mathml/import.hxx b/include/oox/mathml/import.hxx index 92db9a837a70..eefb609178e5 100644 --- a/include/oox/mathml/import.hxx +++ b/include/oox/mathml/import.hxx @@ -26,7 +26,7 @@ class XmlStream; representing the formula and getFormulaSize() to provide the size of the resulting formula. */ -class OOX_DLLPUBLIC FormulaImportBase +class OOX_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") FormulaImportBase { public: virtual void readFormulaOoxml( oox::formulaimport::XmlStream& stream ) = 0; diff --git a/include/sal/types.h b/include/sal/types.h index 7bfb256e3208..df160d2eef50 100644 --- a/include/sal/types.h +++ b/include/sal/types.h @@ -682,6 +682,18 @@ template< typename T1, typename T2 > inline T1 static_int_cast(T2 n) { #endif /// @endcond +#if defined LIBO_INTERNAL_ONLY +// An annotation mechanism used by some loplugins. The id argument must be an ordinary string +// literal. For Clang, this expands to a clang::annotate attribute with an annotation consisting of +// the concatenation of a "loplugin:" prefix and the given id suffix. For non-Clang, this expands +// to nothing to avoid e.g. -Wattributes from GCC's -Wall. +#if defined __clang__ +#define SAL_LOPLUGIN_ANNOTATE(id) [[clang::annotate("loplugin:" id)]] +#else +#define SAL_LOPLUGIN_ANNOTATE(id) +#endif +#endif + #endif // INCLUDED_SAL_TYPES_H /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/sfx2/Metadatable.hxx b/include/sfx2/Metadatable.hxx index a84bddb899b1..ffd9b616e671 100644 --- a/include/sfx2/Metadatable.hxx +++ b/include/sfx2/Metadatable.hxx @@ -63,7 +63,7 @@ createXmlIdRegistry(const bool i_DocIsClipboard); previous hooks</li></ul> </p> */ -class SFX2_DLLPUBLIC Metadatable +class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") Metadatable { public: Metadatable() : m_pReg(nullptr) {} diff --git a/include/sfx2/digitalsignatures.hxx b/include/sfx2/digitalsignatures.hxx index 8f0e161b42a6..b46cdd52e9d9 100644 --- a/include/sfx2/digitalsignatures.hxx +++ b/include/sfx2/digitalsignatures.hxx @@ -19,7 +19,7 @@ namespace sfx2 { /// Extension of css::security::XDocumentDigitalSignatures for internal purposes. -class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI DigitalSignatures +class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") DigitalSignatures { public: /// Same as signDocumentWithCertificate(), but passes the xModel as well. diff --git a/include/sfx2/sidebar/IContextChangeReceiver.hxx b/include/sfx2/sidebar/IContextChangeReceiver.hxx index 784193c0496d..2667201444d5 100644 --- a/include/sfx2/sidebar/IContextChangeReceiver.hxx +++ b/include/sfx2/sidebar/IContextChangeReceiver.hxx @@ -27,7 +27,7 @@ class EnumContext; namespace sfx2::sidebar { -class SFX2_DLLPUBLIC IContextChangeReceiver +class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") IContextChangeReceiver { public: virtual ~IContextChangeReceiver(); diff --git a/include/sfx2/sidebar/ILayoutableWindow.hxx b/include/sfx2/sidebar/ILayoutableWindow.hxx index 344e7fd4fe55..d5124a898362 100644 --- a/include/sfx2/sidebar/ILayoutableWindow.hxx +++ b/include/sfx2/sidebar/ILayoutableWindow.hxx @@ -24,7 +24,7 @@ namespace sfx2::sidebar { -class SFX2_DLLPUBLIC ILayoutableWindow +class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") ILayoutableWindow { public: virtual ~ILayoutableWindow(); diff --git a/include/sfx2/sidebar/SidebarModelUpdate.hxx b/include/sfx2/sidebar/SidebarModelUpdate.hxx index 988478bce7ab..33b273f14345 100644 --- a/include/sfx2/sidebar/SidebarModelUpdate.hxx +++ b/include/sfx2/sidebar/SidebarModelUpdate.hxx @@ -22,7 +22,7 @@ template <typename> class Reference; namespace sfx2::sidebar { -class SFX2_DLLPUBLIC SidebarModelUpdate +class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") SidebarModelUpdate { public: virtual ~SidebarModelUpdate(); diff --git a/include/sfx2/xmldump.hxx b/include/sfx2/xmldump.hxx index 245a07b2285f..cd32d73299e0 100644 --- a/include/sfx2/xmldump.hxx +++ b/include/sfx2/xmldump.hxx @@ -16,7 +16,7 @@ typedef struct _xmlTextWriter* xmlTextWriterPtr; namespace sfx2 { /// Implemented by objects that can be dumped to xml for debugging purposes. -class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI XmlDump +class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") XmlDump { public: virtual void dumpAsXml(xmlTextWriterPtr pWriter) const = 0; diff --git a/include/svl/stylesheetuser.hxx b/include/svl/stylesheetuser.hxx index ba69268da809..24d23a94bde8 100644 --- a/include/svl/stylesheetuser.hxx +++ b/include/svl/stylesheetuser.hxx @@ -22,7 +22,7 @@ namespace svl a SfxStyleSheet (and listen on it). It can be queried by the stylesheet to determine if it is really used. */ -class SAL_DLLPUBLIC_RTTI StyleSheetUser +class SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") StyleSheetUser { public: /** Test whether this object is used. diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx index eff352298a5c..a64a1f5151f3 100644 --- a/include/svl/undo.hxx +++ b/include/svl/undo.hxx @@ -32,7 +32,7 @@ typedef o3tl::strong_int<int, struct ViewShellDocIdTag> ViewShellDocId; typedef struct _xmlTextWriter* xmlTextWriterPtr; -class SVL_DLLPUBLIC SfxRepeatTarget +class SVL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") SfxRepeatTarget { public: virtual ~SfxRepeatTarget() = 0; diff --git a/include/svx/ipolypolygoneditorcontroller.hxx b/include/svx/ipolypolygoneditorcontroller.hxx index 22f7871216a6..401096b6e292 100644 --- a/include/svx/ipolypolygoneditorcontroller.hxx +++ b/include/svx/ipolypolygoneditorcontroller.hxx @@ -47,7 +47,7 @@ enum class SdrObjClosedKind Closed // closed object (polygon, ...) }; -class SAL_DLLPUBLIC_RTTI IPolyPolygonEditorController +class SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") IPolyPolygonEditorController { public: virtual void DeleteMarkedPoints() = 0; diff --git a/include/vcl/IContext.hxx b/include/vcl/IContext.hxx index d595d8771089..f4a913576e4f 100644 --- a/include/vcl/IContext.hxx +++ b/include/vcl/IContext.hxx @@ -16,7 +16,7 @@ namespace vcl { -class VCL_DLLPUBLIC IContext +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") IContext { protected: IContext() { maContext.push_back(vcl::EnumContext::Context::Any); } diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx index 771ecf225c5a..10d0ea87752c 100644 --- a/include/vcl/ITiledRenderable.hxx +++ b/include/vcl/ITiledRenderable.hxx @@ -42,7 +42,7 @@ namespace vcl extern const std::map <PointerStyle, OString> gaLOKPointerMap; -class VCL_DLLPUBLIC ITiledRenderable +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") ITiledRenderable { public: diff --git a/include/vcl/NotebookbarContextControl.hxx b/include/vcl/NotebookbarContextControl.hxx index adb6178e510d..6ded46658548 100644 --- a/include/vcl/NotebookbarContextControl.hxx +++ b/include/vcl/NotebookbarContextControl.hxx @@ -12,7 +12,7 @@ #include <vcl/EnumContext.hxx> -class NotebookbarContextControl +class SAL_LOPLUGIN_ANNOTATE("crosscast") NotebookbarContextControl { public: virtual ~NotebookbarContextControl() {} diff --git a/include/vcl/gdimetafiletools.hxx b/include/vcl/gdimetafiletools.hxx index 665683dd279f..576ba41f372d 100644 --- a/include/vcl/gdimetafiletools.hxx +++ b/include/vcl/gdimetafiletools.hxx @@ -43,7 +43,7 @@ bool usesClipActions(const GDIMetaFile& rSource); // hook to access metafile members in classes of modules above vcl. Currently // used in MetafilePrimitive2D to be able to access the local Metafile member // e.g. from vcl module -class UNLESS_MERGELIBS(VCL_DLLPUBLIC) MetafileAccessor +class UNLESS_MERGELIBS(VCL_DLLPUBLIC) SAL_LOPLUGIN_ANNOTATE("crosscast") MetafileAccessor { public: virtual void accessMetafile(GDIMetaFile& rTargetMetafile) const = 0; diff --git a/include/vcl/syswin.hxx b/include/vcl/syswin.hxx index e2faf1337e62..d370c6399f0e 100644 --- a/include/vcl/syswin.hxx +++ b/include/vcl/syswin.hxx @@ -73,7 +73,7 @@ enum class TitleButton //dispose before the Window dispose; so a Dialog::dispose() method would //finish: disposeBuilder(); SystemWindow::dispose() to capture this ordering. -class VCL_DLLPUBLIC VclBuilderContainer +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") VclBuilderContainer { public: VclBuilderContainer(); diff --git a/include/vcl/toolkit/field.hxx b/include/vcl/toolkit/field.hxx index 836e59591850..10f9cc3b571d 100644 --- a/include/vcl/toolkit/field.hxx +++ b/include/vcl/toolkit/field.hxx @@ -90,7 +90,7 @@ public: bool IsEmptyFieldValueEnabled() const { return mbEmptyFieldValueEnabled; } }; -class VCL_DLLPUBLIC NumericFormatter : public FormatterBase +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") NumericFormatter : public FormatterBase { public: virtual ~NumericFormatter() override; diff --git a/include/vcl/transfer.hxx b/include/vcl/transfer.hxx index bdd8754a9e8a..bd5999a82234 100644 --- a/include/vcl/transfer.hxx +++ b/include/vcl/transfer.hxx @@ -373,7 +373,7 @@ public: const css::datatransfer::DataFlavor& rRequestFlavor ); }; -class VCL_DLLPUBLIC DragSourceHelper +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") DragSourceHelper { private: @@ -419,7 +419,7 @@ public: virtual ~DragSourceHelper(); }; -class VCL_DLLPUBLIC DropTargetHelper +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") DropTargetHelper { private: diff --git a/include/vcl/wizardmachine.hxx b/include/vcl/wizardmachine.hxx index a2ce936630c2..04698f387011 100644 --- a/include/vcl/wizardmachine.hxx +++ b/include/vcl/wizardmachine.hxx @@ -49,7 +49,7 @@ namespace vcl }; }; - class SAL_NO_VTABLE IWizardPageController + class SAL_NO_VTABLE SAL_LOPLUGIN_ANNOTATE("crosscast") IWizardPageController { public: diff --git a/include/xmloff/settingsstore.hxx b/include/xmloff/settingsstore.hxx index ba5526f72195..339e71bbd1a7 100644 --- a/include/xmloff/settingsstore.hxx +++ b/include/xmloff/settingsstore.hxx @@ -20,7 +20,7 @@ namespace com::sun::star::uno { template <typename > class Reference; } // Scans list of properties for certain URL properties that could refer // to internal objects, and initializes from these. -class SAL_DLLPUBLIC_RTTI DocumentSettingsSerializer { +class SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") DocumentSettingsSerializer { public: // Import objects and update properties (eliding URLs) virtual css::uno::Sequence<css::beans::PropertyValue> diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx index 14c7b92556b1..26873175268d 100644 --- a/include/xmloff/xmlimp.hxx +++ b/include/xmloff/xmlimp.hxx @@ -176,7 +176,7 @@ public: virtual void SAL_CALL setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator > & xLocator) override; }; -class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper< +class XMLOFF_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") SvXMLImport : public cppu::WeakImplHelper< css::xml::sax::XFastDocumentHandler, css::lang::XServiceInfo, css::lang::XInitialization, diff --git a/reportdesign/inc/RptObject.hxx b/reportdesign/inc/RptObject.hxx index c2ffe7176331..f0007d3eadca 100644 --- a/reportdesign/inc/RptObject.hxx +++ b/reportdesign/inc/RptObject.hxx @@ -60,7 +60,7 @@ typedef ::std::multimap< sal_Int16, OUString > IndexToNameMap; class OReportPage; class OPropertyMediator; -class REPORTDESIGN_DLLPUBLIC OObjectBase +class REPORTDESIGN_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") OObjectBase { protected: mutable rtl::Reference<OPropertyMediator> m_xMediator; diff --git a/sc/source/ui/inc/IAnyRefDialog.hxx b/sc/source/ui/inc/IAnyRefDialog.hxx index acc8a5bfce8c..9db61ff04e32 100644 --- a/sc/source/ui/inc/IAnyRefDialog.hxx +++ b/sc/source/ui/inc/IAnyRefDialog.hxx @@ -28,7 +28,8 @@ namespace formula class RefEdit; class RefButton; } -class SAL_NO_VTABLE IAnyRefDialog : public formula::IControlReferenceHandler +class SAL_NO_VTABLE SAL_LOPLUGIN_ANNOTATE("crosscast") IAnyRefDialog + : public formula::IControlReferenceHandler { public: virtual ~IAnyRefDialog() COVERITY_NOEXCEPT_FALSE {} diff --git a/sd/source/filter/eppt/epptbase.hxx b/sd/source/filter/eppt/epptbase.hxx index e8ac992e3f1d..c56866b248fe 100644 --- a/sd/source/filter/eppt/epptbase.hxx +++ b/sd/source/filter/eppt/epptbase.hxx @@ -118,7 +118,7 @@ class PropValue }; class EscherGraphicProvider; -class PPTExBulletProvider +class SAL_LOPLUGIN_ANNOTATE("crosscast") PPTExBulletProvider { friend struct PPTExParaSheet; diff --git a/sdext/source/presenter/PresenterViewFactory.hxx b/sdext/source/presenter/PresenterViewFactory.hxx index fa5e888ecad2..7f3468d4e57a 100644 --- a/sdext/source/presenter/PresenterViewFactory.hxx +++ b/sdext/source/presenter/PresenterViewFactory.hxx @@ -39,7 +39,7 @@ typedef ::cppu::WeakComponentImplHelper < /** Base class for presenter views that allows the view factory to store them in a cache and reuse deactivated views. */ -class CachablePresenterView +class SAL_LOPLUGIN_ANNOTATE("crosscast") CachablePresenterView { public: virtual void ActivatePresenterView(); diff --git a/slideshow/source/inc/cursormanager.hxx b/slideshow/source/inc/cursormanager.hxx index cfd5f0a74205..bb014696c028 100644 --- a/slideshow/source/inc/cursormanager.hxx +++ b/slideshow/source/inc/cursormanager.hxx @@ -33,7 +33,7 @@ namespace slideshow::internal Classes implementing this interface interact with the View, arbitrating access to the mouse cursor shape. */ - class CursorManager + class SAL_LOPLUGIN_ANNOTATE("crosscast") CursorManager { public: virtual ~CursorManager() {} diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk index 6e77d57cc2b3..6ea19156854f 100644 --- a/solenv/CompilerTest_compilerplugins_clang.mk +++ b/solenv/CompilerTest_compilerplugins_clang.mk @@ -24,6 +24,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \ compilerplugins/clang/test/consttobool \ compilerplugins/clang/test/cow_wrapper \ compilerplugins/clang/test/cppunitassertequals \ + compilerplugins/clang/test/crosscast \ compilerplugins/clang/test/cstylecast \ compilerplugins/clang/test/datamembershadow \ compilerplugins/clang/test/dbgunhandledexception \ diff --git a/svx/source/inc/celltypes.hxx b/svx/source/inc/celltypes.hxx index 39edf2c5a81e..acc5bdec7caf 100644 --- a/svx/source/inc/celltypes.hxx +++ b/svx/source/inc/celltypes.hxx @@ -39,7 +39,7 @@ typedef std::vector<CellRef> CellVector; typedef std::vector<TableRowRef> RowVector; typedef std::vector<TableColumnRef> ColumnVector; -class TableDesignUser +class SAL_LOPLUGIN_ANNOTATE("crosscast") TableDesignUser { public: virtual bool isInUse() = 0; diff --git a/svx/source/inc/tablemodel.hxx b/svx/source/inc/tablemodel.hxx index 63c08a9b8891..7a2cf4851c7e 100644 --- a/svx/source/inc/tablemodel.hxx +++ b/svx/source/inc/tablemodel.hxx @@ -35,7 +35,7 @@ namespace sdr::table { class SdrTableObj; /** base class for each object implementing an XCellRange */ -class ICellRange +class SAL_LOPLUGIN_ANNOTATE("crosscast") ICellRange { public: virtual sal_Int32 getLeft() = 0; diff --git a/sw/inc/IDocumentUndoRedo.hxx b/sw/inc/IDocumentUndoRedo.hxx index cea231a0c361..e946b5ec4efe 100644 --- a/sw/inc/IDocumentUndoRedo.hxx +++ b/sw/inc/IDocumentUndoRedo.hxx @@ -34,7 +34,7 @@ namespace sw { class RepeatContext; } -class IDocumentUndoRedo +class SAL_LOPLUGIN_ANNOTATE("crosscast") IDocumentUndoRedo { public: diff --git a/sw/inc/IMark.hxx b/sw/inc/IMark.hxx index c256c2ef997c..04b7efa22141 100644 --- a/sw/inc/IMark.hxx +++ b/sw/inc/IMark.hxx @@ -84,7 +84,7 @@ namespace sw::mark IBookmark &operator =(IBookmark const&) = delete; }; - class SW_DLLPUBLIC IFieldmark + class SW_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") IFieldmark : virtual public IMark { protected: diff --git a/sw/inc/calbck.hxx b/sw/inc/calbck.hxx index 26dcd2566fc1..abe556ef6757 100644 --- a/sw/inc/calbck.hxx +++ b/sw/inc/calbck.hxx @@ -223,7 +223,9 @@ namespace sw // Still: in the long run the SwClient/SwModify interface should not be // used anymore, in which case a BroadcasterMixin should be enough instead // then. - class SW_DLLPUBLIC BroadcastingModify : public SwModify, public BroadcasterMixin { + class SW_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") BroadcastingModify : + public SwModify, public BroadcasterMixin + { public: virtual void CallSwClientNotify(const SfxHint& rHint) const override; }; diff --git a/sw/inc/contentindex.hxx b/sw/inc/contentindex.hxx index 2be6bc650879..873e1512ca4f 100644 --- a/sw/inc/contentindex.hxx +++ b/sw/inc/contentindex.hxx @@ -113,7 +113,7 @@ public: SW_DLLPUBLIC std::ostream& operator <<(std::ostream& s, const SwContentIndex& index); /// Helper base class for SwContentNode to manage the list of attached SwContentIndex -class SAL_WARN_UNUSED SwContentIndexReg +class SAL_WARN_UNUSED SAL_LOPLUGIN_ANNOTATE("crosscast") SwContentIndexReg { friend class SwContentIndex; diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx index a5766c793eb7..3eaf2adfb3ca 100644 --- a/sw/source/core/inc/flowfrm.hxx +++ b/sw/source/core/inc/flowfrm.hxx @@ -56,7 +56,7 @@ class SwNodeIndex; FlowFrame can work with the reference to the SwFrame instead of working with its own this-pointer. */ -class SwFlowFrame +class SAL_LOPLUGIN_ANNOTATE("crosscast") SwFlowFrame { // PrepareMake is allowed to lock/unlock (robustness) friend inline void PrepareLock ( SwFlowFrame * ); diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index 9a2ff848de69..517dd5aaa8cd 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -295,6 +295,9 @@ uno::Reference<drawing::XShape> SwFmDrawPage::GetShape(SdrObject* pObj) if(!pObj) return nullptr; SwFrameFormat* pFormat = ::FindFrameFormat( pObj ); + // TODO see comment at + // <https://gerrit.libreoffice.org/c/core/+/78734/4#message-5ee4e724a8073c5c475f07da0b5d79bc34e61de5> + // "make page bookkeep the SwXShapes" [-loplugin:crosscast]: SwFmDrawPage* pPage = dynamic_cast<SwFmDrawPage*>(pFormat); if(!pPage || pPage->m_vShapes.empty()) return uno::Reference<drawing::XShape>(pObj->getUnoShape(), uno::UNO_QUERY); diff --git a/sw/source/uibase/inc/FrameControl.hxx b/sw/source/uibase/inc/FrameControl.hxx index 561dac78fcb7..4ab1d61b0303 100644 --- a/sw/source/uibase/inc/FrameControl.hxx +++ b/sw/source/uibase/inc/FrameControl.hxx @@ -20,7 +20,7 @@ class SwFrame; class Point; /// Abstract interface to be implemented by writer FrameControls -class ISwFrameControl +class SAL_LOPLUGIN_ANNOTATE("crosscast") ISwFrameControl { public: virtual ~ISwFrameControl(); diff --git a/vcl/inc/IPrioritable.hxx b/vcl/inc/IPrioritable.hxx index 55faf6431243..559fbc982f74 100644 --- a/vcl/inc/IPrioritable.hxx +++ b/vcl/inc/IPrioritable.hxx @@ -17,7 +17,7 @@ namespace vcl { -class VCL_DLLPUBLIC IPrioritable +class VCL_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") IPrioritable { protected: IPrioritable() : m_nPriority(VCL_PRIORITY_DEFAULT) diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index a837df4998a1..291fd24babb7 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -318,7 +318,7 @@ private: VclPtr<vcl::Window>& GetNotifierWindow(); }; -class BaseJSWidget +class SAL_LOPLUGIN_ANNOTATE("crosscast") BaseJSWidget { public: virtual ~BaseJSWidget() = default; diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h index 43e4c6bda99e..51c1298089ad 100644 --- a/vcl/inc/unx/x11/x11gdiimpl.h +++ b/vcl/inc/unx/x11/x11gdiimpl.h @@ -14,7 +14,7 @@ class ControlCacheKey; -class X11GraphicsImpl +class SAL_LOPLUGIN_ANNOTATE("crosscast") X11GraphicsImpl { public: virtual ~X11GraphicsImpl(){}; diff --git a/xmlsecurity/inc/certificate.hxx b/xmlsecurity/inc/certificate.hxx index bd24bcd72c00..8357f50651a1 100644 --- a/xmlsecurity/inc/certificate.hxx +++ b/xmlsecurity/inc/certificate.hxx @@ -24,7 +24,7 @@ enum class SignatureMethodAlgorithm; namespace xmlsecurity { /// Extension of css::security::XCertificate for module-internal purposes. -class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI Certificate +class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") Certificate { public: /// Returns the SHA-256 thumbprint. |