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:
Anders Carlsson 2011-03-06 18:19:42 +00:00
parent 189c0e8923
commit 80756f6240
3 changed files with 31 additions and 10 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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);
}
};
}