diff options
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 24 | ||||
-rw-r--r-- | clang/test/Modules/odr_hash.cpp | 18 |
2 files changed, 33 insertions, 9 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 6c8bc7dc33a..19e7ebe03a1 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -10094,14 +10094,22 @@ void ASTReader::diagnoseOdrViolations() { } if (IsFirstBitField && IsSecondBitField) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldDifferentWidthBitField) - << FirstII << FirstField->getBitWidth()->getSourceRange(); - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldDifferentWidthBitField) - << SecondII << SecondField->getBitWidth()->getSourceRange(); - Diagnosed = true; - break; + unsigned FirstBitWidthHash = + ComputeODRHash(FirstField->getBitWidth()); + unsigned SecondBitWidthHash = + ComputeODRHash(SecondField->getBitWidth()); + if (FirstBitWidthHash != SecondBitWidthHash) { + ODRDiagError(FirstField->getLocation(), + FirstField->getSourceRange(), + FieldDifferentWidthBitField) + << FirstII << FirstField->getBitWidth()->getSourceRange(); + ODRDiagNote(SecondField->getLocation(), + SecondField->getSourceRange(), + FieldDifferentWidthBitField) + << SecondII << SecondField->getBitWidth()->getSourceRange(); + Diagnosed = true; + break; + } } const bool IsFirstMutable = FirstField->isMutable(); diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp index ff7cfb3ae7f..6d26b3cfb57 100644 --- a/clang/test/Modules/odr_hash.cpp +++ b/clang/test/Modules/odr_hash.cpp @@ -311,6 +311,20 @@ S9 s9; #endif #if defined(FIRST) +struct S9b { + mutable int x : 2; +}; +#elif defined(SECOND) +struct S9b { + int x : 2; +}; +#else +S9b s9b; +// expected-error@second.h:* {{'Field::S9b' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}} +// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}} +#endif + +#if defined(FIRST) struct S10 { unsigned x = 5; }; @@ -372,7 +386,9 @@ S13 s13; unsigned c : 1 + 2; \ s d; \ double e = 1.0; \ - long f[5]; + long f[5]; \ + mutable int g; \ + mutable int h : 5; #if defined(FIRST) || defined(SECOND) typedef short s; |