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
29 class StringConcatAuto
30 : public FilteringPlugin
< StringConcatAuto
>
33 StringConcatAuto( const InstantiationData
& data
);
34 virtual void run() override
;
35 bool shouldVisitTemplateInstantiations () const { return true; }
36 bool VisitVarDecl( const VarDecl
* decl
);
37 bool VisitFunctionDecl( const FunctionDecl
* decl
);
39 enum class Check
{ Var
, Return
};
40 bool checkDecl( const DeclaratorDecl
* decl
, const QualType type
, const SourceRange
& range
, Check check
);
43 StringConcatAuto::StringConcatAuto( const InstantiationData
& data
)
44 : FilteringPlugin( data
)
48 void StringConcatAuto::run()
50 TraverseDecl( compiler
.getASTContext().getTranslationUnitDecl());
53 bool StringConcatAuto::VisitVarDecl( const VarDecl
* decl
)
55 return checkDecl( decl
, decl
->getType(),
56 decl
->getTypeSourceInfo()
57 ? decl
->getTypeSourceInfo()->getTypeLoc().getSourceRange()
58 : decl
->getSourceRange(),
62 bool StringConcatAuto::VisitFunctionDecl( const FunctionDecl
* decl
)
64 return checkDecl( decl
, decl
->getReturnType(), decl
->getReturnTypeSourceRange(), Check::Return
);
67 bool StringConcatAuto::checkDecl( const DeclaratorDecl
* decl
, QualType type
, const SourceRange
& range
, Check check
)
69 if( ignoreLocation( decl
))
71 if( isa
< ParmVarDecl
>( decl
)) // parameters should be fine, temporaries should exist during the call
73 std::string fileName
= getFilenameOfLocation(
74 compiler
.getSourceManager().getSpellingLoc(compat::getBeginLoc(decl
))).str();
75 loplugin::normalizeDotDotInFilePath(fileName
);
76 if (loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/string.hxx")
77 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/ustring.hxx")
78 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/strbuf.hxx")
79 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/ustrbuf.hxx")
80 || loplugin::isSamePathname(fileName
, SRCDIR
"/include/rtl/stringconcat.hxx"))
82 auto const tc
= loplugin::TypeCheck( type
.getNonReferenceType().getCanonicalType());
83 const char* typeString
= nullptr;
84 if( tc
.Struct("OUStringConcat").Namespace("rtl").GlobalNamespace())
85 typeString
= "OUString";
86 else if( tc
.Struct("OStringConcat").Namespace("rtl").GlobalNamespace())
87 typeString
= "OString";
88 else if( tc
.Struct("OUStringNumber").Namespace("rtl").GlobalNamespace())
89 typeString
= "OUString";
90 else if( tc
.Struct("OStringNumber").Namespace("rtl").GlobalNamespace())
91 typeString
= "OString";
94 report( DiagnosticsEngine::Warning
,
96 ? "creating a variable of type %0 will make it reference temporaries"
97 : "returning a variable of type %0 will make it reference temporaries",
100 report( DiagnosticsEngine::Note
,
104 << FixItHint::CreateReplacement( range
, typeString
);
108 static Plugin::Registration
< StringConcatAuto
> stringconcatauto( "stringconcatauto" );
112 #endif // LO_CLANG_SHARED_PLUGINS
114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */