[clang] a60e892 - [ODRHash] Fix wrong error message with bitfields and mutable.

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 14 21:27:58 PST 2020


Author: Weverything
Date: 2020-01-14T21:12:15-08:00
New Revision: a60e8927297005898b10a46300d929ba5cf7833c

URL: https://github.com/llvm/llvm-project/commit/a60e8927297005898b10a46300d929ba5cf7833c
DIFF: https://github.com/llvm/llvm-project/commit/a60e8927297005898b10a46300d929ba5cf7833c.diff

LOG: [ODRHash] Fix wrong error message with bitfields and mutable.

Add a check to bitfield mismatches that may have caused Clang to
give an error about the bitfield instead of being mutable.

Added: 
    

Modified: 
    clang/lib/Serialization/ASTReader.cpp
    clang/test/Modules/odr_hash.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 6c8bc7dc33a9..19e7ebe03a1f 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 ff7cfb3ae7fd..6d26b3cfb570 100644
--- a/clang/test/Modules/odr_hash.cpp
+++ b/clang/test/Modules/odr_hash.cpp
@@ -310,6 +310,20 @@ S9 s9;
 // expected-note at first.h:* {{but in 'FirstModule' found mutable field 'x'}}
 #endif
 
+#if defined(FIRST)
+struct S9b {
+  mutable int x : 2;
+};
+#elif defined(SECOND)
+struct S9b {
+  int x : 2;
+};
+#else
+S9b s9b;
+// expected-error at second.h:* {{'Field::S9b' has 
diff erent definitions in 
diff erent modules; first 
diff erence is definition in module 'SecondModule' found non-mutable field 'x'}}
+// expected-note at 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;


        


More information about the cfe-commits mailing list