[cfe-commits] r127125 - in /cfe/trunk: lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp test/PCH/cxx-templates.cpp

Douglas Gregor dgregor at apple.com
Sun Mar 6 10:46:05 PST 2011


On Mar 6, 2011, at 10:19 AM, Anders Carlsson wrote:

> Author: andersca
> Date: Sun Mar  6 12:19:42 2011
> New Revision: 127125
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=127125&view=rev
> Log:
> 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.

Awesome, thank you!

I just scanned through the rest of the expressions that can have explicit template arguments, and no others were affected by this bug.

	- Doug

> Modified:
>    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>    cfe/trunk/test/PCH/cxx-templates.cpp
> 
> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=127125&r1=127124&r2=127125&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sun Mar  6 12:19:42 2011
> @@ -423,21 +423,21 @@
> 
>   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));
> 
> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=127125&r1=127124&r2=127125&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sun Mar  6 12:19:42 2011
> @@ -382,15 +382,17 @@
>   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);
> 
> Modified: cfe/trunk/test/PCH/cxx-templates.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=127125&r1=127124&r2=127125&view=diff
> ==============================================================================
> --- cfe/trunk/test/PCH/cxx-templates.cpp (original)
> +++ cfe/trunk/test/PCH/cxx-templates.cpp Sun Mar  6 12:19:42 2011
> @@ -43,3 +43,22 @@
> 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);
> +    }
> +  };
> +}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list