bump product version to 6.4.0.3
[LibreOffice.git] / compilerplugins / clang / unicodetochar.cxx
blob3599d3081a9f7f3651d03a63e04765dd79fa999f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #ifndef LO_CLANG_SHARED_PLUGINS
12 #include <stack>
14 #include "check.hxx"
15 #include "plugin.hxx"
17 // In C++, find implicit conversions from char16_t (aka sal_Unicode) to char.
18 // Such places are probably meant to properly work on char16_t instead.
20 namespace {
22 class UnicodeToChar final:
23 public loplugin::FilteringPlugin<UnicodeToChar>
25 public:
26 explicit UnicodeToChar(loplugin::InstantiationData const & data):
27 FilteringPlugin(data) {}
29 bool PreTraverseCStyleCastExpr(CStyleCastExpr * expr) {
30 subExprs_.push(expr->getSubExpr());
31 return true;
33 bool PostTraverseCStyleCastExpr(CStyleCastExpr *, bool ) {
34 subExprs_.pop();
35 return true;
37 bool TraverseCStyleCastExpr(CStyleCastExpr * expr) {
38 PreTraverseCStyleCastExpr(expr);
39 bool ret = RecursiveASTVisitor::TraverseCStyleCastExpr(expr);
40 PostTraverseCStyleCastExpr(expr, ret);
41 return ret;
44 bool PreTraverseCXXStaticCastExpr(CXXStaticCastExpr * expr) {
45 subExprs_.push(expr->getSubExpr());
46 return true;
48 bool PostTraverseCXXStaticCastExpr(CXXStaticCastExpr *, bool) {
49 subExprs_.pop();
50 return true;
52 bool TraverseCXXStaticCastExpr(CXXStaticCastExpr * expr) {
53 PreTraverseCXXStaticCastExpr(expr);
54 bool ret = RecursiveASTVisitor::TraverseCXXStaticCastExpr(expr);
55 PostTraverseCXXStaticCastExpr(expr, ret);
56 return ret;
59 bool PreTraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr * expr) {
60 subExprs_.push(expr->getSubExpr());
61 return true;
63 bool PostTraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr *, bool) {
64 subExprs_.pop();
65 return true;
67 bool TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr * expr) {
68 PreTraverseCXXFunctionalCastExpr(expr);
69 bool ret = RecursiveASTVisitor::TraverseCXXFunctionalCastExpr(expr);
70 PostTraverseCXXFunctionalCastExpr(expr, ret);
71 return ret;
74 bool VisitImplicitCastExpr(ImplicitCastExpr const * expr) {
75 if ((!subExprs_.empty() && expr == subExprs_.top())
76 || ignoreLocation(expr))
78 return true;
80 if (!(loplugin::TypeCheck(expr->getType()).Char()
81 && expr->getSubExpr()->getType()->isSpecificBuiltinType(
82 clang::BuiltinType::Char16)))
84 return true;
86 APSInt res;
87 if (compat::EvaluateAsInt(expr->getSubExpr(), res, compiler.getASTContext())
88 && res >= 0 && res <= 0x7F)
90 return true;
92 report(
93 DiagnosticsEngine::Warning,
94 "suspicious implicit cast from %0 to %1",
95 expr->getExprLoc())
96 << expr->getSubExpr()->getType() << expr->getType()
97 << expr->getSourceRange();
98 return true;
101 bool preRun() override {
102 return compiler.getLangOpts().CPlusPlus;
105 void run() override {
106 if (preRun()) {
107 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
111 private:
112 std::stack<Expr const *> subExprs_;
115 static loplugin::Plugin::Registration<UnicodeToChar> unicodetochar("unicodetochar");
117 } // namespace
119 #endif // LO_CLANG_SHARED_PLUGINS
121 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */