d1a2b80b9d
...as discussed in the mail thread starting at <https://lists.freedesktop.org/archives/libreoffice/2020-November/086234.html> "Bump --enable-compiler-plugins Clang baseline?" (and now picked up again at <https://lists.freedesktop.org/archives/libreoffice/2022-February/088459.html> "Re: Bump --enable-compiler-plugins Clang baseline?"), and clean up compilerplugins/clang/ accordingly Change-Id: I5e81c6fdcc363aeefd6227606225b526fdf7ac16 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129989 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
116 lines
4 KiB
C++
116 lines
4 KiB
C++
/* -*- 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.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
This is a compile check.
|
|
|
|
Warns about 'auto' declarations becoming rtl::OUStringConcat, such as
|
|
auto str = "string" + OUString::number( 10 );
|
|
The type of the expression is rtl::OUStringConcat and those refer to temporaries
|
|
and so their lifecycle should not extend the lifecycle of those temporaries.
|
|
*/
|
|
|
|
#ifndef LO_CLANG_SHARED_PLUGINS
|
|
|
|
#include "config_clang.h"
|
|
|
|
#include "plugin.hxx"
|
|
#include "check.hxx"
|
|
|
|
namespace loplugin
|
|
{
|
|
|
|
class StringConcatAuto
|
|
: public FilteringPlugin< StringConcatAuto >
|
|
{
|
|
public:
|
|
StringConcatAuto( const InstantiationData& data );
|
|
virtual void run() override;
|
|
bool shouldVisitTemplateInstantiations () const { return true; }
|
|
bool VisitVarDecl( const VarDecl* decl );
|
|
bool VisitFunctionDecl( const FunctionDecl* decl );
|
|
private:
|
|
enum class Check { Var, Return };
|
|
bool checkDecl( const DeclaratorDecl* decl, const QualType type, const SourceRange& range, Check check );
|
|
};
|
|
|
|
StringConcatAuto::StringConcatAuto( const InstantiationData& data )
|
|
: FilteringPlugin( data )
|
|
{
|
|
}
|
|
|
|
void StringConcatAuto::run()
|
|
{
|
|
TraverseDecl( compiler.getASTContext().getTranslationUnitDecl());
|
|
}
|
|
|
|
bool StringConcatAuto::VisitVarDecl( const VarDecl* decl )
|
|
{
|
|
return checkDecl( decl, decl->getType(),
|
|
decl->getTypeSourceInfo()
|
|
? decl->getTypeSourceInfo()->getTypeLoc().getSourceRange()
|
|
: decl->getSourceRange(),
|
|
Check::Var );
|
|
}
|
|
|
|
bool StringConcatAuto::VisitFunctionDecl( const FunctionDecl* decl )
|
|
{
|
|
return checkDecl( decl, decl->getReturnType(), decl->getReturnTypeSourceRange(), Check::Return );
|
|
}
|
|
|
|
bool StringConcatAuto::checkDecl( const DeclaratorDecl* decl, QualType type, const SourceRange& range, Check check )
|
|
{
|
|
if( ignoreLocation( decl ))
|
|
return true;
|
|
if( isa< ParmVarDecl >( decl )) // parameters should be fine, temporaries should exist during the call
|
|
return true;
|
|
std::string fileName = getFilenameOfLocation(
|
|
compiler.getSourceManager().getSpellingLoc(decl->getBeginLoc())).str();
|
|
loplugin::normalizeDotDotInFilePath(fileName);
|
|
if (loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/string.hxx")
|
|
|| loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/ustring.hxx")
|
|
|| loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/strbuf.hxx")
|
|
|| loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/ustrbuf.hxx")
|
|
|| loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/stringconcat.hxx"))
|
|
return true;
|
|
auto const tc = loplugin::TypeCheck( type.getNonReferenceType().getCanonicalType());
|
|
const char* typeString = nullptr;
|
|
if( tc.Struct("OUStringConcat").Namespace("rtl").GlobalNamespace())
|
|
typeString = "OUString";
|
|
else if( tc.Struct("OStringConcat").Namespace("rtl").GlobalNamespace())
|
|
typeString = "OString";
|
|
else if( tc.Struct("OUStringNumber").Namespace("rtl").GlobalNamespace())
|
|
typeString = "OUString";
|
|
else if( tc.Struct("OStringNumber").Namespace("rtl").GlobalNamespace())
|
|
typeString = "OString";
|
|
else
|
|
return true;
|
|
report( DiagnosticsEngine::Warning,
|
|
check == Check::Var
|
|
? "creating a variable of type %0 will make it reference temporaries"
|
|
: "returning a variable of type %0 will make it reference temporaries",
|
|
decl->getLocation())
|
|
<< type;
|
|
report( DiagnosticsEngine::Note,
|
|
"use %0 instead",
|
|
range.getBegin())
|
|
<< typeString
|
|
<< FixItHint::CreateReplacement( range, typeString );
|
|
return true;
|
|
}
|
|
|
|
static Plugin::Registration< StringConcatAuto > stringconcatauto( "stringconcatauto" );
|
|
|
|
} // namespace
|
|
|
|
#endif // LO_CLANG_SHARED_PLUGINS
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|