| Index: tools/clang/plugins/CheckIPCVisitor.cpp
|
| diff --git a/tools/clang/plugins/CheckIPCVisitor.cpp b/tools/clang/plugins/CheckIPCVisitor.cpp
|
| deleted file mode 100644
|
| index b123b0130ed1c5dd3d5690476a149a84187271ab..0000000000000000000000000000000000000000
|
| --- a/tools/clang/plugins/CheckIPCVisitor.cpp
|
| +++ /dev/null
|
| @@ -1,288 +0,0 @@
|
| -// Copyright (c) 2016 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "CheckIPCVisitor.h"
|
| -
|
| -using namespace clang;
|
| -
|
| -namespace chrome_checker {
|
| -
|
| -namespace {
|
| -
|
| -const char kWriteParamBadType[] =
|
| - "[chromium-ipc] IPC::WriteParam() is called on blacklisted type '%0'%1.";
|
| -
|
| -const char kTupleBadType[] =
|
| - "[chromium-ipc] IPC tuple references banned type '%0'%1.";
|
| -
|
| -const char kWriteParamBadSignature[] =
|
| - "[chromium-ipc] IPC::WriteParam() is expected to have two arguments.";
|
| -
|
| -const char kNoteSeeHere[] =
|
| - "see here";
|
| -
|
| -} // namespace
|
| -
|
| -CheckIPCVisitor::CheckIPCVisitor(CompilerInstance& compiler)
|
| - : compiler_(compiler), context_(nullptr) {
|
| - auto& diagnostics = compiler_.getDiagnostics();
|
| - error_write_param_bad_type_ = diagnostics.getCustomDiagID(
|
| - DiagnosticsEngine::Error, kWriteParamBadType);
|
| - error_tuple_bad_type_ = diagnostics.getCustomDiagID(
|
| - DiagnosticsEngine::Error, kTupleBadType);
|
| - error_write_param_bad_signature_ = diagnostics.getCustomDiagID(
|
| - DiagnosticsEngine::Error, kWriteParamBadSignature);
|
| - note_see_here_ = diagnostics.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kNoteSeeHere);
|
| -
|
| - blacklisted_typedefs_ = llvm::StringSet<>({
|
| - "intmax_t",
|
| - "uintmax_t",
|
| - "intptr_t",
|
| - "uintptr_t",
|
| - "wint_t",
|
| - "size_t",
|
| - "rsize_t",
|
| - "ssize_t",
|
| - "ptrdiff_t",
|
| - "dev_t",
|
| - "off_t",
|
| - "clock_t",
|
| - "time_t",
|
| - "suseconds_t"
|
| - });
|
| -}
|
| -
|
| -void CheckIPCVisitor::BeginDecl(Decl* decl) {
|
| - decl_stack_.push_back(decl);
|
| -}
|
| -
|
| -void CheckIPCVisitor::EndDecl() {
|
| - decl_stack_.pop_back();
|
| -}
|
| -
|
| -void CheckIPCVisitor::VisitTemplateSpecializationType(
|
| - TemplateSpecializationType* spec) {
|
| - ValidateCheckedTuple(spec);
|
| -}
|
| -
|
| -void CheckIPCVisitor::VisitCallExpr(CallExpr* call_expr) {
|
| - ValidateWriteParam(call_expr);
|
| -}
|
| -
|
| -bool CheckIPCVisitor::ValidateWriteParam(const CallExpr* call_expr) {
|
| - const FunctionDecl* callee_decl = call_expr->getDirectCallee();
|
| - if (!callee_decl ||
|
| - callee_decl->getQualifiedNameAsString() != "IPC::WriteParam") {
|
| - return true;
|
| - }
|
| -
|
| - return ValidateWriteParamSignature(call_expr) &&
|
| - ValidateWriteParamArgument(call_expr->getArg(1));
|
| -}
|
| -
|
| -// Checks that IPC::WriteParam() has expected signature.
|
| -bool CheckIPCVisitor::ValidateWriteParamSignature(
|
| - const CallExpr* call_expr) {
|
| - if (call_expr->getNumArgs() != 2) {
|
| - compiler_.getDiagnostics().Report(
|
| - call_expr->getExprLoc(), error_write_param_bad_signature_);
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -// Checks that IPC::WriteParam() argument type is allowed.
|
| -// See CheckType() for specifics.
|
| -bool CheckIPCVisitor::ValidateWriteParamArgument(const Expr* arg_expr) {
|
| - if (auto* parent_fn_decl = GetParentDecl<FunctionDecl>()) {
|
| - auto template_kind = parent_fn_decl->getTemplatedKind();
|
| - if (template_kind != FunctionDecl::TK_NonTemplate &&
|
| - template_kind != FunctionDecl::TK_FunctionTemplate) {
|
| - // Skip all specializations - we don't check WriteParam() on dependent
|
| - // types (typedef info gets lost), and we checked all non-dependent uses
|
| - // earlier (when we checked the template itself).
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - QualType arg_type;
|
| -
|
| - arg_expr = arg_expr->IgnoreImplicit();
|
| - if (auto* cast_expr = dyn_cast<ExplicitCastExpr>(arg_expr)) {
|
| - arg_type = cast_expr->getTypeAsWritten();
|
| - } else {
|
| - arg_type = arg_expr->getType();
|
| - }
|
| -
|
| - CheckDetails details;
|
| - if (CheckType(arg_type, &details)) {
|
| - return true;
|
| - }
|
| -
|
| - ReportCheckError(details,
|
| - arg_expr->getExprLoc(),
|
| - error_write_param_bad_type_);
|
| -
|
| - return false;
|
| -}
|
| -
|
| -// Checks that IPC::CheckedTuple<> is specialized with allowed types.
|
| -// See CheckType() above for specifics.
|
| -bool CheckIPCVisitor::ValidateCheckedTuple(
|
| - const TemplateSpecializationType* spec) {
|
| - TemplateDecl* decl = spec->getTemplateName().getAsTemplateDecl();
|
| - if (!decl || decl->getQualifiedNameAsString() != "IPC::CheckedTuple") {
|
| - return true;
|
| - }
|
| -
|
| - bool valid = true;
|
| - for (unsigned i = 0; i != spec->getNumArgs(); ++i) {
|
| - const TemplateArgument& arg = spec->getArg(i);
|
| - CheckDetails details;
|
| - if (CheckTemplateArgument(arg, &details)) {
|
| - continue;
|
| - }
|
| -
|
| - valid = false;
|
| -
|
| - auto* parent_decl = GetParentDecl<Decl>();
|
| - ReportCheckError(
|
| - details,
|
| - parent_decl ? parent_decl->getLocStart() : SourceLocation(),
|
| - error_tuple_bad_type_);
|
| - }
|
| -
|
| - return valid;
|
| -}
|
| -
|
| -template <typename T>
|
| -const T* CheckIPCVisitor::GetParentDecl() const {
|
| - for (auto i = decl_stack_.rbegin(); i != decl_stack_.rend(); ++i) {
|
| - if (auto* parent = dyn_cast_or_null<T>(*i)) {
|
| - return parent;
|
| - }
|
| - }
|
| - return nullptr;
|
| -}
|
| -
|
| -
|
| -bool CheckIPCVisitor::IsBlacklistedType(QualType type) const {
|
| - return context_->hasSameUnqualifiedType(type, context_->LongTy) ||
|
| - context_->hasSameUnqualifiedType(type, context_->UnsignedLongTy);
|
| -}
|
| -
|
| -bool CheckIPCVisitor::IsBlacklistedTypedef(const TypedefNameDecl* tdef) const {
|
| - return blacklisted_typedefs_.find(tdef->getName()) !=
|
| - blacklisted_typedefs_.end();
|
| -}
|
| -
|
| -// Checks that integer type is allowed (not blacklisted).
|
| -bool CheckIPCVisitor::CheckIntegerType(QualType type,
|
| - CheckDetails* details) const {
|
| - bool seen_typedef = false;
|
| - while (true) {
|
| - details->exit_type = type;
|
| -
|
| - if (auto* tdef = dyn_cast<TypedefType>(type)) {
|
| - if (IsBlacklistedTypedef(tdef->getDecl())) {
|
| - return false;
|
| - }
|
| - details->typedefs.push_back(tdef);
|
| - seen_typedef = true;
|
| - }
|
| -
|
| - QualType desugared_type =
|
| - type->getLocallyUnqualifiedSingleStepDesugaredType();
|
| - if (desugared_type == type) {
|
| - break;
|
| - }
|
| -
|
| - type = desugared_type;
|
| - }
|
| -
|
| - return seen_typedef || !IsBlacklistedType(type);
|
| -}
|
| -
|
| -// Checks that |type| is allowed (not blacklisted), recursively visiting
|
| -// template specializations.
|
| -bool CheckIPCVisitor::CheckType(QualType type, CheckDetails* details) const {
|
| - if (type->isReferenceType()) {
|
| - type = type->getPointeeType();
|
| - }
|
| - type = type.getLocalUnqualifiedType();
|
| -
|
| - if (details->entry_type.isNull()) {
|
| - details->entry_type = type;
|
| - }
|
| -
|
| - if (type->isIntegerType()) {
|
| - return CheckIntegerType(type, details);
|
| - }
|
| -
|
| - while (true) {
|
| - if (auto* spec = dyn_cast<TemplateSpecializationType>(type)) {
|
| - for (const TemplateArgument& arg: *spec) {
|
| - if (!CheckTemplateArgument(arg, details)) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - if (auto* record = dyn_cast<RecordType>(type)) {
|
| - if (auto* spec = dyn_cast<ClassTemplateSpecializationDecl>(
|
| - record->getDecl())) {
|
| - const TemplateArgumentList& args = spec->getTemplateArgs();
|
| - for (unsigned i = 0; i != args.size(); ++i) {
|
| - if (!CheckTemplateArgument(args[i], details)) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - if (auto* tdef = dyn_cast<TypedefType>(type)) {
|
| - details->typedefs.push_back(tdef);
|
| - }
|
| -
|
| - QualType desugared_type =
|
| - type->getLocallyUnqualifiedSingleStepDesugaredType();
|
| - if (desugared_type == type) {
|
| - break;
|
| - }
|
| -
|
| - type = desugared_type;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool CheckIPCVisitor::CheckTemplateArgument(const TemplateArgument& arg,
|
| - CheckDetails* details) const {
|
| - return arg.getKind() != TemplateArgument::Type ||
|
| - CheckType(arg.getAsType(), details);
|
| -}
|
| -
|
| -void CheckIPCVisitor::ReportCheckError(const CheckDetails& details,
|
| - SourceLocation loc,
|
| - unsigned error) {
|
| - DiagnosticsEngine& diagnostics = compiler_.getDiagnostics();
|
| -
|
| - std::string entry_type = details.entry_type.getAsString();
|
| - std::string exit_type = details.exit_type.getAsString();
|
| -
|
| - std::string via;
|
| - if (entry_type != exit_type) {
|
| - via = " via '" + entry_type + "'";
|
| - }
|
| - diagnostics.Report(loc, error) << exit_type << via;
|
| -
|
| - for (const TypedefType* tdef: details.typedefs) {
|
| - diagnostics.Report(tdef->getDecl()->getLocation(), note_see_here_);
|
| - }
|
| -}
|
| -
|
| -} // namespace chrome_checker
|
|
|