Author: rtrieu Date: Fri Feb 24 17:35:37 2017 New Revision: 296198 URL: http://llvm.org/viewvc/llvm-project?rev=296198&view=rev Log: [ODRHash] Finish FieldDecl support by handling mutable and initializers.
https://reviews.llvm.org/rL296170 Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=296198&r1=296197&r2=296198&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Fri Feb 24 17:35:37 2017 @@ -136,7 +136,10 @@ def err_module_odr_violation_mismatch_de "field %4|" "field %4 with type %5|" "%select{non-|}5bitfield %4|" - "bitfield %4 with one width expression}3">; + "bitfield %4 with one width expression|" + "%select{non-|}5mutable field %4|" + "field %4 with %select{no|an}5 initalizer|" + "field %4 with an initializer}3">; def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "%select{" @@ -146,7 +149,10 @@ def note_module_odr_violation_mismatch_d "field %2|" "field %2 with type %3|" "%select{non-|}3bitfield %2|" - "bitfield %2 with different width expression}1">; + "bitfield %2 with different width expression|" + "%select{non-|}3mutable field %2|" + "field %2 with %select{no|an}3 initializer|" + "field %2 with a different initializer}1">; def warn_module_uses_date_time : Warning< "%select{precompiled header|module}0 uses __DATE__ or __TIME__">, Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=296198&r1=296197&r2=296198&view=diff ============================================================================== --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Fri Feb 24 17:35:37 2017 @@ -190,6 +190,9 @@ public: if (IsBitfield) { AddStmt(D->getBitWidth()); } + + Hash.AddBoolean(D->isMutable()); + AddStmt(D->getInClassInitializer()); } }; Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=296198&r1=296197&r2=296198&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Feb 24 17:35:37 2017 @@ -9064,7 +9064,10 @@ void ASTReader::diagnoseOdrViolations() FieldName, FieldTypeName, FieldSingleBitField, - FieldDifferentWidthBitField + FieldDifferentWidthBitField, + FieldSingleMutable, + FieldSingleInitializer, + FieldDifferentInitializers, }; // These lambdas have the common portions of the ODR diagnostics. This @@ -9239,6 +9242,50 @@ void ASTReader::diagnoseOdrViolations() break; } + const bool IsFirstMutable = FirstField->isMutable(); + const bool IsSecondMutable = SecondField->isMutable(); + if (IsFirstMutable != IsSecondMutable) { + ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), + FieldSingleMutable) + << FirstII << IsFirstMutable; + ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), + FieldSingleMutable) + << SecondII << IsSecondMutable; + Diagnosed = true; + break; + } + + const Expr *FirstInitializer = FirstField->getInClassInitializer(); + const Expr *SecondInitializer = SecondField->getInClassInitializer(); + if ((!FirstInitializer && SecondInitializer) || + (FirstInitializer && !SecondInitializer)) { + ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), + FieldSingleInitializer) + << FirstII << (FirstInitializer != nullptr); + ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), + FieldSingleInitializer) + << SecondII << (SecondInitializer != nullptr); + Diagnosed = true; + break; + } + + if (FirstInitializer && SecondInitializer) { + unsigned FirstInitHash = ComputeODRHash(FirstInitializer); + unsigned SecondInitHash = ComputeODRHash(SecondInitializer); + if (FirstInitHash != SecondInitHash) { + ODRDiagError(FirstField->getLocation(), + FirstField->getSourceRange(), + FieldDifferentInitializers) + << FirstII << FirstInitializer->getSourceRange(); + ODRDiagNote(SecondField->getLocation(), + SecondField->getSourceRange(), + FieldDifferentInitializers) + << SecondII << SecondInitializer->getSourceRange(); + Diagnosed = true; + break; + } + } + break; } } Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=296198&r1=296197&r2=296198&view=diff ============================================================================== --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Fri Feb 24 17:35:37 2017 @@ -233,6 +233,48 @@ S8 s8; // expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}} #endif +#if defined(FIRST) +struct S9 { + mutable int x; +}; +#elif defined(SECOND) +struct S9 { + int x; +}; +#else +S9 s9; +// expected-error@second.h:* {{'Field::S9' 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; +}; +#elif defined(SECOND) +struct S10 { + unsigned x; +}; +#else +S10 s10; +// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}} +#endif + +#if defined(FIRST) +struct S11 { + unsigned x = 5; +}; +#elif defined(SECOND) +struct S11 { + unsigned x = 7; +}; +#else +S11 s11; +// expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}} +#endif + } // namespace Field // Naive parsing of AST can lead to cycles in processing. Ensure @@ -280,6 +322,8 @@ struct S { unsigned a : 1; unsigned b : 2*2 + 5/2; + + mutable int c = sizeof(x + y); }; #elif defined(SECOND) typedef int INT; @@ -298,6 +342,8 @@ struct S { unsigned a : 1; unsigned b : 2 * 2 + 5 / 2; + + mutable int c = sizeof(x + y); }; #else S s; @@ -321,6 +367,8 @@ struct T { unsigned a : 1; unsigned b : 2 * 2 + 5 / 2; + mutable int c = sizeof(x + y); + private: }; #elif defined(SECOND) @@ -341,6 +389,8 @@ struct T { unsigned a : 1; unsigned b : 2 * 2 + 5 / 2; + mutable int c = sizeof(x + y); + public: }; #else _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits