1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright (c) 2016 The Chromium Authors. All rights reserved. 2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// found in the LICENSE file. 4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "CheckIPCVisitor.h" 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing namespace clang; 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace chrome_checker { 10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char kWriteParamBadType[] = 14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "[chromium-ipc] IPC::WriteParam() is called on blacklisted type '%0'%1."; 15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char kTupleBadType[] = 17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "[chromium-ipc] IPC tuple references banned type '%0'%1."; 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char kWriteParamBadSignature[] = 20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "[chromium-ipc] IPC::WriteParam() is expected to have two arguments."; 21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char kNoteSeeHere[] = 23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "see here"; 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochCheckIPCVisitor::CheckIPCVisitor(CompilerInstance& compiler) 28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : compiler_(compiler), context_(nullptr) { 29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto& diagnostics = compiler_.getDiagnostics(); 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch error_write_param_bad_type_ = diagnostics.getCustomDiagID( 31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DiagnosticsEngine::Error, kWriteParamBadType); 32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch error_tuple_bad_type_ = diagnostics.getCustomDiagID( 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DiagnosticsEngine::Error, kTupleBadType); 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch error_write_param_bad_signature_ = diagnostics.getCustomDiagID( 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DiagnosticsEngine::Error, kWriteParamBadSignature); 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch note_see_here_ = diagnostics.getCustomDiagID( 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DiagnosticsEngine::Note, kNoteSeeHere); 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch blacklisted_typedefs_ = llvm::StringSet<>({ 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "intmax_t", 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "uintmax_t", 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "intptr_t", 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "uintptr_t", 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "wint_t", 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "size_t", 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "rsize_t", 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "ssize_t", 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "ptrdiff_t", 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "dev_t", 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "off_t", 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "clock_t", 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "time_t", 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "suseconds_t" 54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch }); 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CheckIPCVisitor::BeginDecl(Decl* decl) { 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch decl_stack_.push_back(decl); 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CheckIPCVisitor::EndDecl() { 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch decl_stack_.pop_back(); 63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CheckIPCVisitor::VisitTemplateSpecializationType( 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TemplateSpecializationType* spec) { 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ValidateCheckedTuple(spec); 68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CheckIPCVisitor::VisitCallExpr(CallExpr* call_expr) { 71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ValidateWriteParam(call_expr); 72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::ValidateWriteParam(const CallExpr* call_expr) { 75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const FunctionDecl* callee_decl = call_expr->getDirectCallee(); 76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!callee_decl || 77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch callee_decl->getQualifiedNameAsString() != "IPC::WriteParam") { 78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ValidateWriteParamSignature(call_expr) && 82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ValidateWriteParamArgument(call_expr->getArg(1)); 83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Checks that IPC::WriteParam() has expected signature. 86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::ValidateWriteParamSignature( 87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const CallExpr* call_expr) { 88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (call_expr->getNumArgs() != 2) { 89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch compiler_.getDiagnostics().Report( 90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch call_expr->getExprLoc(), error_write_param_bad_signature_); 91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Checks that IPC::WriteParam() argument type is allowed. 97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// See CheckType() for specifics. 98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::ValidateWriteParamArgument(const Expr* arg_expr) { 99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* parent_fn_decl = GetParentDecl<FunctionDecl>()) { 100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto template_kind = parent_fn_decl->getTemplatedKind(); 101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (template_kind != FunctionDecl::TK_NonTemplate && 102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch template_kind != FunctionDecl::TK_FunctionTemplate) { 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Skip all specializations - we don't check WriteParam() on dependent 104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // types (typedef info gets lost), and we checked all non-dependent uses 105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // earlier (when we checked the template itself). 106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch QualType arg_type; 111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch arg_expr = arg_expr->IgnoreImplicit(); 113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* cast_expr = dyn_cast<ExplicitCastExpr>(arg_expr)) { 114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch arg_type = cast_expr->getTypeAsWritten(); 115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch arg_type = arg_expr->getType(); 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CheckDetails details; 120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CheckType(arg_type, &details)) { 121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReportCheckError(details, 125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch arg_expr->getExprLoc(), 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch error_write_param_bad_type_); 127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Checks that IPC::CheckedTuple<> is specialized with allowed types. 132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// See CheckType() above for specifics. 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::ValidateCheckedTuple( 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const TemplateSpecializationType* spec) { 135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TemplateDecl* decl = spec->getTemplateName().getAsTemplateDecl(); 136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!decl || decl->getQualifiedNameAsString() != "IPC::CheckedTuple") { 137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool valid = true; 141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (unsigned i = 0; i != spec->getNumArgs(); ++i) { 142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const TemplateArgument& arg = spec->getArg(i); 143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CheckDetails details; 144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CheckTemplateArgument(arg, &details)) { 145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch valid = false; 149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto* parent_decl = GetParentDecl<Decl>(); 151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReportCheckError( 152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch details, 153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch parent_decl ? parent_decl->getLocStart() : SourceLocation(), 154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch error_tuple_bad_type_); 155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return valid; 158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T> 161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst T* CheckIPCVisitor::GetParentDecl() const { 162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto i = decl_stack_.rbegin(); i != decl_stack_.rend(); ++i) { 163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* parent = dyn_cast_or_null<T>(*i)) { 164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return parent; 165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return nullptr; 168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::IsBlacklistedType(QualType type) const { 172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return context_->hasSameUnqualifiedType(type, context_->LongTy) || 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context_->hasSameUnqualifiedType(type, context_->UnsignedLongTy); 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::IsBlacklistedTypedef(const TypedefNameDecl* tdef) const { 177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return blacklisted_typedefs_.find(tdef->getName()) != 178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch blacklisted_typedefs_.end(); 179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Checks that integer type is allowed (not blacklisted). 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::CheckIntegerType(QualType type, 183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CheckDetails* details) const { 184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool seen_typedef = false; 185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch while (true) { 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch details->exit_type = type; 187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* tdef = dyn_cast<TypedefType>(type)) { 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsBlacklistedTypedef(tdef->getDecl())) { 190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch details->typedefs.push_back(tdef); 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch seen_typedef = true; 194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch QualType desugared_type = 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type->getLocallyUnqualifiedSingleStepDesugaredType(); 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (desugared_type == type) { 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type = desugared_type; 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return seen_typedef || !IsBlacklistedType(type); 206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Checks that |type| is allowed (not blacklisted), recursively visiting 209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// template specializations. 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::CheckType(QualType type, CheckDetails* details) const { 211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (type->isReferenceType()) { 212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type = type->getPointeeType(); 213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type = type.getLocalUnqualifiedType(); 215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (details->entry_type.isNull()) { 217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch details->entry_type = type; 218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (type->isIntegerType()) { 221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return CheckIntegerType(type, details); 222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch while (true) { 225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* spec = dyn_cast<TemplateSpecializationType>(type)) { 226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (const TemplateArgument& arg: *spec) { 227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!CheckTemplateArgument(arg, details)) { 228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* record = dyn_cast<RecordType>(type)) { 235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* spec = dyn_cast<ClassTemplateSpecializationDecl>( 236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch record->getDecl())) { 237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const TemplateArgumentList& args = spec->getTemplateArgs(); 238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (unsigned i = 0; i != args.size(); ++i) { 239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!CheckTemplateArgument(args[i], details)) { 240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (auto* tdef = dyn_cast<TypedefType>(type)) { 248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch details->typedefs.push_back(tdef); 249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch QualType desugared_type = 252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type->getLocallyUnqualifiedSingleStepDesugaredType(); 253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (desugared_type == type) { 254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type = desugared_type; 258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CheckIPCVisitor::CheckTemplateArgument(const TemplateArgument& arg, 264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CheckDetails* details) const { 265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return arg.getKind() != TemplateArgument::Type || 266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CheckType(arg.getAsType(), details); 267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CheckIPCVisitor::ReportCheckError(const CheckDetails& details, 270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SourceLocation loc, 271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unsigned error) { 272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DiagnosticsEngine& diagnostics = compiler_.getDiagnostics(); 273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::string entry_type = details.entry_type.getAsString(); 275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::string exit_type = details.exit_type.getAsString(); 276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::string via; 278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (entry_type != exit_type) { 279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch via = " via '" + entry_type + "'"; 280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch diagnostics.Report(loc, error) << exit_type << via; 282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (const TypedefType* tdef: details.typedefs) { 284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch diagnostics.Report(tdef->getDecl()->getLocation(), note_see_here_); 285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace chrome_checker 289