When serializing a DeclRefExpr, always store the number of explicit template
arguments at the same offset, since it's needed when creating the empty DeclRefExpr when deserializing. Fixes a memory corruption issue that would lead to random bugs and crashes. llvm-svn: 127125
This commit is contained in:
parent
189c0e8923
commit
80756f6240
|
@ -423,21 +423,21 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
|
|||
|
||||
bool HasQualifier = Record[Idx++];
|
||||
bool HasExplicitTemplateArgs = Record[Idx++];
|
||||
|
||||
unsigned NumTemplateArgs = 0;
|
||||
if (HasExplicitTemplateArgs)
|
||||
NumTemplateArgs = Record[Idx++];
|
||||
|
||||
E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) |
|
||||
(HasExplicitTemplateArgs
|
||||
? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0));
|
||||
|
||||
if (HasQualifier) {
|
||||
if (HasQualifier)
|
||||
E->getNameQualifier()->QualifierLoc
|
||||
= Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
||||
}
|
||||
|
||||
if (HasExplicitTemplateArgs) {
|
||||
unsigned NumTemplateArgs = Record[Idx++];
|
||||
if (HasExplicitTemplateArgs)
|
||||
ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
|
||||
NumTemplateArgs);
|
||||
}
|
||||
|
||||
E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setLocation(ReadSourceLocation(Record, Idx));
|
||||
|
|
|
@ -382,15 +382,17 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
|
|||
Record.push_back(E->hasQualifier());
|
||||
Record.push_back(E->hasExplicitTemplateArgs());
|
||||
|
||||
if (E->hasQualifier())
|
||||
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
||||
|
||||
if (E->hasExplicitTemplateArgs()) {
|
||||
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
||||
Record.push_back(NumTemplateArgs);
|
||||
AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
|
||||
}
|
||||
|
||||
if (E->hasQualifier())
|
||||
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
||||
|
||||
if (E->hasExplicitTemplateArgs())
|
||||
AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
|
||||
|
||||
Writer.AddDeclRef(E->getDecl(), Record);
|
||||
Writer.AddSourceLocation(E->getLocation(), Record);
|
||||
Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
|
||||
|
|
|
@ -43,3 +43,22 @@ S7<int[5]> s7_5;
|
|||
namespace ZeroLengthExplicitTemplateArgs {
|
||||
template void f<X>(X*);
|
||||
}
|
||||
|
||||
// This used to overwrite memory and crash.
|
||||
namespace Test1 {
|
||||
struct StringHasher {
|
||||
template<typename T, char Converter(T)> static inline unsigned createHash(const T*, unsigned) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct CaseFoldingHash {
|
||||
static inline char foldCase(char) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned hash(const char* data, unsigned length) {
|
||||
return StringHasher::createHash<char, foldCase>(data, length);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue