Index: clang/lib/AST/ODRHash.cpp =================================================================== --- clang/lib/AST/ODRHash.cpp +++ clang/lib/AST/ODRHash.cpp @@ -172,7 +172,10 @@ AddDecl(TA.getAsDecl()); break; case TemplateArgument::NullPtr: + ID.AddPointer(nullptr); + break; case TemplateArgument::Integral: + ID.AddInteger(TA.getAsIntegral().getLimitedValue()); break; case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: Index: clang/test/Modules/odr_hash.cpp =================================================================== --- clang/test/Modules/odr_hash.cpp +++ clang/test/Modules/odr_hash.cpp @@ -1939,6 +1939,99 @@ // expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 2 template arguments}} #endif +#if defined(FIRST) +struct S12 { + template void f(){}; + template <> void f<1>(){}; +}; +#elif defined(SECOND) +struct S12 { + template void f(){}; + template <> void f<2>(){}; +}; +#else +S12 s12; +// expected-error@second.h:* {{'TemplateArgument::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with 2 for 1st template argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 1 for 1st template argument}} +#endif + +#if defined(FIRST) +struct S13 { + template void f(){}; + template <> void f<10>(){}; +}; +#elif defined(SECOND) +struct S13 { + template void f(){}; + template <> void f<10>(){}; +}; +#else +S13 s13; +#endif + +#if defined(FIRST) +struct S14 { + template void f(){}; + template <> void f(){}; +}; +#elif defined(SECOND) +struct S14 { + template void f(){}; + template <> void f(){}; +}; +#else +S14 s14; +// expected-error@second.h:* {{'TemplateArgument::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with 0 for 1st template argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 1 for 1st template argument}} +#endif + +#if defined(FIRST) +struct S15 { + template void f(){}; + template <> void f(){}; +}; +#elif defined(SECOND) +struct S15 { + template void f(){}; + template <> void f(){}; +}; +#else +S15 s15; +#endif + +#if defined(FIRST) +struct S16 { + template void f(){}; + template <> void f(){}; +}; +#elif defined(SECOND) +struct S16 { + template void f(){}; + template <> void f(){}; +}; +#else +S16 s16; +#endif + +#if defined(FIRST) +struct S17 { + static int x; + template void f(){}; + template <> void f<&x>(){}; +}; +#elif defined(SECOND) +struct S17 { + static int x; + template void f(){}; + template <> void f(){}; +}; +#else +S17 s17; +// expected-error@second.h:* {{'TemplateArgument::S17' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with nullptr for 1st template argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 'x' for 1st template argument}} +#endif + + #define DECLS \ OneClass a; \ OneInt<1> b; \