1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
13 This is a compile check.
15 Warns about 'auto' declarations becoming rtl::OUStringConcat, such as
16 auto str = "string" + OUString::number( 10 );
17 The type of the expression is rtl::OUStringConcat and those refer to temporaries
18 and so their lifecycle should not extend the lifecycle of those temporaries.
21 #ifndef LO_CLANG_SHARED_PLUGINS
23 #include "config_clang.h"
31 class StringConcatAuto
32 : public FilteringPlugin
< StringConcatAuto
>
35 StringConcatAuto( const InstantiationData
& data
);
36 virtual void run() override
;
37 bool shouldVisitTemplateInstantiations () const { return true; }
38 bool VisitVarDecl( const VarDecl
* decl
);
39 bool VisitFunctionDecl( const FunctionDecl
* decl
);
41 enum class Check
{ Var
, Return
};
42 bool checkDecl( const DeclaratorDecl
* decl
, const QualType type
, const SourceRange
& range
, Check check
);
45 StringConcatAuto::StringConcatAuto( const InstantiationData
& data
)
46 : FilteringPlugin( data
)
50 void StringConcatAuto::run()
52 TraverseDecl( compiler
.getASTContext().getTranslationUnitDecl());
55 bool StringConcatAuto::VisitVarDecl( const VarDecl
* decl
)
57 return checkDecl( decl
, decl
->getType(),
58 decl
->getTypeSourceInfo()
59 ? decl
->getTypeSourceInfo()->getTypeLoc().getSourceRange()
60 : decl
->getSourceRange(),
64 bool StringConcatAuto::VisitFunctionDecl( const FunctionDecl
* decl
)
66 return checkDecl( decl
, decl
->getReturnType(), decl
->getReturnTypeSourceRange(), Check::Return
);
69 bool StringConcatAuto::checkDecl( const DeclaratorDecl
* decl
, QualType type
, const SourceRange
& range
, Check check
)
71 if( ignoreLocation( decl
))
73 if( isa
< ParmVarDecl
>( decl
)) // parameters should be fine, temporaries should exist during the call
75 std::string fileName
= getFilenameOfLocation(
76 compiler
.getSourceManager().getSpellingLoc(decl
->getBeginLoc())).str();
77 loplugin::normalizeDotDotInFilePath(fileName
);
78 if (loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/string.hxx")
79 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/ustring.hxx")
80 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/strbuf.hxx")
81 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/ustrbuf.hxx")
82 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/stringconcat.hxx"))
84 auto const tc
= loplugin::TypeCheck( type
.getNonReferenceType().getCanonicalType());
85 const char* typeString
= nullptr;
86 if( tc
.Struct("StringConcat").Namespace("rtl").GlobalNamespace())
87 typeString
= "O(U)String";
90 report( DiagnosticsEngine::Warning
,
92 ? "creating a variable of type %0 will make it reference temporaries"
93 : "returning a variable of type %0 will make it reference temporaries",
96 report( DiagnosticsEngine::Note
,
100 << FixItHint::CreateReplacement( range
, typeString
);
104 static Plugin::Registration
< StringConcatAuto
> stringconcatauto( "stringconcatauto" );
108 #endif // LO_CLANG_SHARED_PLUGINS
110 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */