martong updated this revision to Diff 176687.
martong added a comment.
- Use clang_analyze_cc1
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/Basic/DiagnosticGroups.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,22 @@
+// 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 \
+// RUN: -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_analyze_cc1 -triple x86_64-unknown-linux-gnu \
+// RUN: -analyzer-checker=core,debug.ExprInspection \
+// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN: -analyzer-config ctu-dir=%t/ctudir \
+// RUN: -Werror=ctu \
+// RUN: -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,20 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
+// RUN: -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_analyze_cc1 -triple powerpc64-montavista-linux-gnu \
+// RUN: -analyzer-checker=core,debug.ExprInspection \
+// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN: -analyzer-config ctu-dir=%t/ctudir \
+// RUN: -Werror=ctu \
+// RUN: -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,31 @@
assert(&Unit->getFileManager() ==
&Unit->getASTContext().getSourceManager().getFileManager());
+ const llvm::Triple &TripleTo = Context.getTargetInfo().getTriple();
+ const llvm::Triple &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: Add statistics here.
+ // TODO: Pass the SourceLocation of the CallExpression for more precise
+ // diagnostics.
+ return llvm::make_error<IndexError>(index_error_code::triple_mismatch,
+ Unit->getMainFileName(), TripleTo.str(),
+ TripleFrom.str());
+ }
+
+ 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))
@@ -187,6 +246,10 @@
Context.getDiagnostics().Report(diag::err_multiple_def_index)
<< IE.getLineNum();
break;
+ case index_error_code::triple_mismatch:
+ Context.getDiagnostics().Report(diag::warn_ctu_incompat_triple)
+ << IE.getFileName() << IE.getTripleToName() << IE.getTripleFromName();
+ break;
default:
break;
}
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> {
@@ -50,16 +52,25 @@
IndexError(index_error_code C) : Code(C), LineNo(0) {}
IndexError(index_error_code C, std::string FileName, int LineNo = 0)
: Code(C), FileName(std::move(FileName)), LineNo(LineNo) {}
+ IndexError(index_error_code C, std::string FileName, std::string TripleToName,
+ std::string TripleFromName)
+ : Code(C), FileName(std::move(FileName)),
+ TripleToName(std::move(TripleToName)),
+ TripleFromName(std::move(TripleFromName)) {}
void log(raw_ostream &OS) const override;
std::error_code convertToErrorCode() const override;
index_error_code getCode() const { return Code; }
int getLineNum() const { return LineNo; }
std::string getFileName() const { return FileName; }
+ std::string getTripleToName() const { return TripleToName; }
+ std::string getTripleFromName() const { return TripleFromName; }
private:
index_error_code Code;
std::string FileName;
int LineNo;
+ std::string TripleToName;
+ std::string TripleFromName;
};
/// This function parses an index file that determines which
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -1039,3 +1039,6 @@
// A warning group specifically for warnings related to function
// multiversioning.
def FunctionMultiVersioning : DiagGroup<"function-multiversion">;
+
+// A group for cross translation unit static analysis related warnings.
+def CrossTU : DiagGroup<"ctu">;
Index: include/clang/Basic/DiagnosticCrossTUKinds.td
===================================================================
--- include/clang/Basic/DiagnosticCrossTUKinds.td
+++ include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -15,4 +15,8 @@
def err_multiple_def_index : Error<
"multiple definitions are found for the same key in index ">;
+
+def warn_ctu_incompat_triple : Warning<
+ "imported AST from '%0' had been generated for a different target, "
+ "current: %1, imported: %2">, InGroup<CrossTU>;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits