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 |