summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2017-12-23 00:41:01 +0000
committerRichard Trieu <rtrieu@google.com>2017-12-23 00:41:01 +0000
commit2532eb8b470984c1ade117bdf79dd23d07358431 (patch)
tree37a42c2af9c563cd8bf8f2dfbc3c24b134dbc912 /include
parentc4dbfb41a7a00efba9e3c8c58839a16e8444c110 (diff)
[ODRHash] Support ODR violation detection in functions.
Extend the hashing to functions, which allows detection of function definition mismatches across modules. This is a re-commit of r320230. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321395 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/Decl.h14
-rw-r--r--include/clang/AST/ODRHash.h4
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td23
-rw-r--r--include/clang/Serialization/ASTReader.h4
4 files changed, 43 insertions, 2 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 4db0b1ef94..04a832e552 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1759,6 +1759,11 @@ protected:
unsigned IsCopyDeductionCandidate : 1;
private:
+
+ /// Store the ODRHash after first calculation.
+ unsigned HasODRHash : 1;
+ unsigned ODRHash;
+
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@@ -1841,8 +1846,9 @@ protected:
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false),
- WillHaveBody(false), IsCopyDeductionCandidate(false),
- EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {}
+ WillHaveBody(false), IsCopyDeductionCandidate(false), HasODRHash(false),
+ ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()),
+ DNLoc(NameInfo.getInfo()) {}
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -2439,6 +2445,10 @@ public:
/// returns 0.
unsigned getMemoryFunctionKind() const;
+ /// \brief Returns ODRHash of the function. This value is calculated and
+ /// stored on first call, then the stored value returned on the other calls.
+ unsigned getODRHash();
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h
index e4cc12d358..ed648bb8af 100644
--- a/include/clang/AST/ODRHash.h
+++ b/include/clang/AST/ODRHash.h
@@ -53,6 +53,10 @@ public:
// more information than the AddDecl class.
void AddCXXRecordDecl(const CXXRecordDecl *Record);
+ // Use this for ODR checking functions between modules. This method compares
+ // more information than the AddDecl class.
+ void AddFunctionDecl(const FunctionDecl *Function);
+
// Process SubDecls of the main Decl. This method calls the DeclVisitor
// while AddDecl does not.
void AddSubDecl(const Decl *D);
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 3949bc2146..250b49f2ca 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -270,6 +270,29 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"friend function %2|"
"}1">;
+def err_module_odr_violation_function : Error<
+ "%q0 has different definitions in different modules; "
+ "%select{definition in module '%2'|defined here}1 "
+ "first difference is "
+ "%select{"
+ "return type is %4|"
+ "%ordinal4 parameter with name %5|"
+ "%ordinal4 parameter with type %5%select{| decayed from %7}6|"
+ "%ordinal4 parameter with%select{out|}5 a default argument|"
+ "%ordinal4 parameter with a default argument|"
+ "function body"
+ "}3">;
+
+def note_module_odr_violation_function : Note<"but in '%0' found "
+ "%select{"
+ "different return type %2|"
+ "%ordinal2 parameter with name %3|"
+ "%ordinal2 parameter with type %3%select{| decayed from %5}4|"
+ "%ordinal2 parameter with%select{out|}3 a default argument|"
+ "%ordinal2 parameter with a different default argument|"
+ "a different body"
+ "}1">;
+
def err_module_odr_violation_mismatch_decl_unknown : Error<
"%q0 %select{with definition in module '%2'|defined here}1 has different "
"definitions in different modules; first difference is this "
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 7b71fee95d..37920fc143 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1092,6 +1092,10 @@ private:
llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2>
PendingOdrMergeFailures;
+ /// \brief Function definitions in which we found an ODR violation.
+ llvm::SmallDenseMap<FunctionDecl *, llvm::SmallVector<FunctionDecl *, 2>, 2>
+ PendingFunctionOdrMergeFailures;
+
/// \brief DeclContexts in which we have diagnosed an ODR violation.
llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;