summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 72d4c75b063..932803885fa 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9062,6 +9062,7 @@ void ASTReader::diagnoseOdrViolations() {
StaticAssertMessage,
StaticAssertOnlyMessage,
FieldName,
+ FieldTypeName,
};
// These lambdas have the common portions of the ODR diagnostics. This
@@ -9086,6 +9087,12 @@ void ASTReader::diagnoseOdrViolations() {
return Hash.CalculateHash();
};
+ auto ComputeDeclNameODRHash = [&Hash](const DeclarationName Name) {
+ Hash.clear();
+ Hash.AddDeclarationName(Name);
+ return Hash.CalculateHash();
+ };
+
switch (FirstDiffType) {
case Other:
case EndOfClass:
@@ -9166,6 +9173,46 @@ void ASTReader::diagnoseOdrViolations() {
Diagnosed = true;
break;
}
+
+ assert(
+ Context.hasSameType(FirstField->getType(), SecondField->getType()));
+
+ QualType FirstType = FirstField->getType();
+ QualType SecondType = SecondField->getType();
+ const TypedefType *FirstTypedef = dyn_cast<TypedefType>(FirstType);
+ const TypedefType *SecondTypedef = dyn_cast<TypedefType>(SecondType);
+
+ if ((FirstTypedef && !SecondTypedef) ||
+ (!FirstTypedef && SecondTypedef)) {
+ ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+ FieldTypeName)
+ << FirstII << FirstType;
+ ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+ FieldTypeName)
+ << SecondII << SecondType;
+
+ Diagnosed = true;
+ break;
+ }
+
+ if (FirstTypedef && SecondTypedef) {
+ unsigned FirstHash = ComputeDeclNameODRHash(
+ FirstTypedef->getDecl()->getDeclName());
+ unsigned SecondHash = ComputeDeclNameODRHash(
+ SecondTypedef->getDecl()->getDeclName());
+ if (FirstHash != SecondHash) {
+ ODRDiagError(FirstField->getLocation(),
+ FirstField->getSourceRange(), FieldTypeName)
+ << FirstII << FirstType;
+ ODRDiagNote(SecondField->getLocation(),
+ SecondField->getSourceRange(), FieldTypeName)
+ << SecondII << SecondType;
+
+ Diagnosed = true;
+ break;
+ }
+ }
+
break;
}
}
OpenPOWER on IntegriCloud