tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NonTrivialTypeInFfiChecker.cpp (1945B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "NonTrivialTypeInFfiChecker.h"
      6 #include "CustomMatchers.h"
      7 
      8 void NonTrivialTypeInFfiChecker::registerMatchers(MatchFinder *AstMatcher) {
      9  AstMatcher->addMatcher(functionDecl(isExternC()).bind("func"), this);
     10 }
     11 
     12 void NonTrivialTypeInFfiChecker::check(const MatchFinder::MatchResult &Result) {
     13  static DenseSet<const FunctionDecl *> CheckedFunctionDecls;
     14 
     15  const FunctionDecl *func = Result.Nodes.getNodeAs<FunctionDecl>("func");
     16  // Don't report errors on the same declarations more than once.
     17  if (!CheckedFunctionDecls.insert(func).second) {
     18    return;
     19  }
     20 
     21  if (inThirdPartyPath(func)) {
     22    return;
     23  }
     24 
     25  auto NoteFor = [](const QualType &T) -> std::string {
     26    std::string s = "Please consider using a pointer or reference";
     27    if (T->getAs<TemplateSpecializationType>()) {
     28      s += ", or explicitly instantiating the template";
     29    }
     30    return s + " instead";
     31  };
     32 
     33  for (ParmVarDecl *p : func->parameters()) {
     34    QualType T = p->getType().getUnqualifiedType();
     35    if (!T->isVoidType() && !T->isReferenceType() &&
     36        !T.isTriviallyCopyableType(*Result.Context)) {
     37      diag(p->getLocation(),
     38           "Type %0 must not be used as parameter to extern "
     39           "\"C\" function",
     40           DiagnosticIDs::Error)
     41          << T;
     42      diag(p->getLocation(), NoteFor(T), DiagnosticIDs::Note);
     43    }
     44  }
     45 
     46  QualType T = func->getReturnType().getUnqualifiedType();
     47  if (!T->isVoidType() && !T->isReferenceType() &&
     48      !T.isTriviallyCopyableType(*Result.Context)) {
     49    diag(func->getLocation(),
     50         "Type %0 must not be used as return type of "
     51         "extern \"C\" function",
     52         DiagnosticIDs::Error)
     53        << T;
     54    diag(func->getLocation(), NoteFor(T), DiagnosticIDs::Note);
     55  }
     56 }