martong updated this revision to Diff 176417.
martong marked 13 inline comments as done.
martong added a comment.

- Address review comments


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55134/new/

https://reviews.llvm.org/D55134

Files:
  include/clang/Basic/DiagnosticCrossTUKinds.td
  include/clang/CrossTU/CrossTranslationUnit.h
  lib/CrossTU/CrossTranslationUnit.cpp
  test/Analysis/ctu-different-triples.cpp
  test/Analysis/ctu-unknown-parts-in-triples.cpp

Index: test/Analysis/ctu-unknown-parts-in-triples.cpp
===================================================================
--- /dev/null
+++ test/Analysis/ctu-unknown-parts-in-triples.cpp
@@ -0,0 +1,16 @@
+// We do not expect any error when one part of the triple is unknown, but other
+// known parts are equal.
+
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
+// RUN: cp %S/Inputs/externalFnMap.txt %t/ctudir/externalFnMap.txt
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config experimental-enable-naive-ctu-analysis=true -analyzer-config ctu-dir=%t/ctudir -verify %s
+
+// expected-no-diagnostics
+
+int f(int);
+
+int main() {
+  return f(5);
+}
Index: test/Analysis/ctu-different-triples.cpp
===================================================================
--- /dev/null
+++ test/Analysis/ctu-different-triples.cpp
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
+// RUN: cp %S/Inputs/externalFnMap.txt %t/ctudir/externalFnMap.txt
+// RUN: %clang_cc1 -triple powerpc64-montavista-linux-gnu -fsyntax-only -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config experimental-enable-naive-ctu-analysis=true -analyzer-config ctu-dir=%t/ctudir -verify %s
+
+// We expect an error in this file, but without a location.
+// expected-error-re@./ctu-different-triples.cpp:*{{imported AST from {{.*}} had been generated for a different target, current: powerpc64-montavista-linux-gnu, imported: x86_64-pc-linux-gnu}}
+
+int f(int);
+
+int main() {
+  return f(5);
+}
Index: lib/CrossTU/CrossTranslationUnit.cpp
===================================================================
--- lib/CrossTU/CrossTranslationUnit.cpp
+++ lib/CrossTU/CrossTranslationUnit.cpp
@@ -32,6 +32,36 @@
 namespace cross_tu {
 
 namespace {
+
+// Same as Triple's equality operator, but we check a field only if that is
+// known in both instances.
+bool hasEqualKnownFields(const llvm::Triple &Lhs, const llvm::Triple &Rhs) {
+  using llvm::Triple;
+  if (Lhs.getArch() != Triple::UnknownArch &&
+      Rhs.getArch() != Triple::UnknownArch && Lhs.getArch() != Rhs.getArch())
+    return false;
+  if (Lhs.getSubArch() != Triple::NoSubArch &&
+      Rhs.getSubArch() != Triple::NoSubArch &&
+      Lhs.getSubArch() != Rhs.getSubArch())
+    return false;
+  if (Lhs.getVendor() != Triple::UnknownVendor &&
+      Rhs.getVendor() != Triple::UnknownVendor &&
+      Lhs.getVendor() != Rhs.getVendor())
+    return false;
+  if (!Lhs.isOSUnknown() && !Rhs.isOSUnknown() &&
+      Lhs.getOS() != Rhs.getOS())
+    return false;
+  if (Lhs.getEnvironment() != Triple::UnknownEnvironment &&
+      Rhs.getEnvironment() != Triple::UnknownEnvironment &&
+      Lhs.getEnvironment() != Rhs.getEnvironment())
+    return false;
+  if (Lhs.getObjectFormat() != Triple::UnknownObjectFormat &&
+      Rhs.getObjectFormat() != Triple::UnknownObjectFormat &&
+      Lhs.getObjectFormat() != Rhs.getObjectFormat())
+    return false;
+  return true;
+}
+
 // FIXME: This class is will be removed after the transition to llvm::Error.
 class IndexErrorCategory : public std::error_category {
 public:
@@ -55,6 +85,10 @@
       return "Failed to load external AST source.";
     case index_error_code::failed_to_generate_usr:
       return "Failed to generate USR.";
+    case index_error_code::triple_mismatch:
+      return "Triple mismatch";
+    case index_error_code::lang_mismatch:
+      return "Language mismatch";
     }
     llvm_unreachable("Unrecognized index_error_code.");
   }
@@ -166,6 +200,30 @@
   assert(&Unit->getFileManager() ==
          &Unit->getASTContext().getSourceManager().getFileManager());
 
+  const auto &TripleTo = Context.getTargetInfo().getTriple();
+  const auto &TripleFrom = Unit->getASTContext().getTargetInfo().getTriple();
+  // The imported AST had been generated for a different target.
+  // Some parts of the triple in the loaded ASTContext can be unknown while the
+  // very same parts in the target ASTContext are known. Thus we check for the
+  // known parts only.
+  if (!hasEqualKnownFields(TripleTo, TripleFrom)) {
+    // TODO: Pass the SourceLocation of the CallExpression for more precise
+    // diagnostics.
+    Context.getDiagnostics().Report(diag::err_ctu_incompat_triple)
+        << Unit->getMainFileName() << TripleTo.str() << TripleFrom.str();
+    // TODO: Add statistics here.
+    return llvm::make_error<IndexError>(index_error_code::triple_mismatch);
+  }
+
+  const auto &LangTo = Context.getLangOpts();
+  const auto &LangFrom = Unit->getASTContext().getLangOpts();
+  // FIXME: Currenty we do not support CTU across C++ and C and across
+  // different dialects of C++.
+  if (LangTo.CPlusPlus != LangFrom.CPlusPlus) {
+    // TODO: Add statistics here.
+    return llvm::make_error<IndexError>(index_error_code::lang_mismatch);
+  }
+
   TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
   if (const FunctionDecl *ResultDecl =
           findFunctionInDeclContext(TU, LookupFnName))
Index: include/clang/CrossTU/CrossTranslationUnit.h
===================================================================
--- include/clang/CrossTU/CrossTranslationUnit.h
+++ include/clang/CrossTU/CrossTranslationUnit.h
@@ -41,7 +41,9 @@
   missing_definition,
   failed_import,
   failed_to_get_external_ast,
-  failed_to_generate_usr
+  failed_to_generate_usr,
+  triple_mismatch,
+  lang_mismatch
 };
 
 class IndexError : public llvm::ErrorInfo<IndexError> {
Index: include/clang/Basic/DiagnosticCrossTUKinds.td
===================================================================
--- include/clang/Basic/DiagnosticCrossTUKinds.td
+++ include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -15,4 +15,7 @@
 
 def err_multiple_def_index : Error<
   "multiple definitions are found for the same key in index ">;
+
+def err_ctu_incompat_triple : Error<
+  "imported AST from '%0' had been generated for a different target, current: %1, imported: %2">;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to