llvm-project
65 строк · 2.7 Кб
1//===--- UncheckedOptionalAccessCheck.cpp - clang-tidy --------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "UncheckedOptionalAccessCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12#include "clang/ASTMatchers/ASTMatchers.h"13#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"14#include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"15#include "clang/Basic/SourceLocation.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/Support/Error.h"18
19namespace clang::tidy::bugprone {20using ast_matchers::MatchFinder;21using dataflow::UncheckedOptionalAccessDiagnoser;22using dataflow::UncheckedOptionalAccessModel;23
24static constexpr llvm::StringLiteral FuncID("fun");25
26void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) {27using namespace ast_matchers;28
29auto HasOptionalCallDescendant = hasDescendant(callExpr(callee(cxxMethodDecl(30ofClass(UncheckedOptionalAccessModel::optionalClassDecl())))));31Finder->addMatcher(32decl(anyOf(functionDecl(unless(isExpansionInSystemHeader()),33// FIXME: Remove the filter below when lambdas are34// well supported by the check.35unless(hasDeclContext(cxxRecordDecl(isLambda()))),36hasBody(HasOptionalCallDescendant)),37cxxConstructorDecl(hasAnyConstructorInitializer(38withInitializer(HasOptionalCallDescendant)))))39.bind(FuncID),40this);41}
42
43void UncheckedOptionalAccessCheck::check(44const MatchFinder::MatchResult &Result) {45if (Result.SourceManager->getDiagnostics().hasUncompilableErrorOccurred())46return;47
48const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(FuncID);49if (FuncDecl->isTemplated())50return;51
52UncheckedOptionalAccessDiagnoser Diagnoser(ModelOptions);53// FIXME: Allow user to set the (defaulted) SAT iterations max for54// `diagnoseFunction` with config options.55if (llvm::Expected<llvm::SmallVector<SourceLocation>> Locs =56dataflow::diagnoseFunction<UncheckedOptionalAccessModel,57SourceLocation>(*FuncDecl, *Result.Context,58Diagnoser))59for (const SourceLocation &Loc : *Locs)60diag(Loc, "unchecked access to optional value");61else62llvm::consumeError(Locs.takeError());63}
64
65} // namespace clang::tidy::bugprone66