[cfe-commits] r156133 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/DeclTemplate.cpp lib/Serialization/ASTWriterDecl.cpp test/CodeGenCXX/debug-info-determinism.cpp

Chandler Carruth chandlerc at gmail.com
Thu May 3 16:49:05 PDT 2012


Author: chandlerc
Date: Thu May  3 18:49:05 2012
New Revision: 156133

URL: http://llvm.org/viewvc/llvm-project?rev=156133&view=rev
Log:
Fix non-deterministic iteration order when walking the specializations
of templates by using the newly introduce FoldingSetVector. This
preserves insertion order for all iteration of specializations.

I've also included a somewhat terrifying testcase that rapidly builds up
a large number of functions. This is enough that any system with ASLR
will have non-deterministic debug information generated for the test
case without the fix here as the debug information is generated in part
by walking these specializations.

Added:
    cfe/trunk/test/CodeGenCXX/debug-info-determinism.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=156133&r1=156132&r2=156133&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu May  3 18:49:05 2012
@@ -512,7 +512,8 @@
     typedef _SETraits SETraits;
     typedef _DeclType DeclType;
 
-    typedef typename llvm::FoldingSet<EntryType>::iterator SetIteratorType;
+    typedef typename llvm::FoldingSetVector<EntryType>::iterator
+      SetIteratorType;
 
     SetIteratorType SetIter;
 
@@ -541,13 +542,13 @@
   };
 
   template <typename EntryType>
-  SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSet<EntryType> &Specs,
-                                           bool isEnd) {
+  SpecIterator<EntryType>
+  makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
     return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
   }
 
   template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
-  findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs,
+  findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
                          const TemplateArgument *Args, unsigned NumArgs,
                          void *&InsertPos);
 
@@ -706,7 +707,7 @@
 
     /// \brief The function template specializations for this function
     /// template, including explicit specializations and instantiations.
-    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+    llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
 
     /// \brief The set of "injected" template arguments used within this
     /// function template.
@@ -732,13 +733,14 @@
 
   /// \brief Retrieve the set of function template specializations of this
   /// function template.
-  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+  llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
+  getSpecializations() {
     return getCommonPtr()->Specializations;
   }
 
   /// \brief Add a specialization of this function template.
   ///
-  /// \param InsertPos Insert position in the FoldingSet, must have been
+  /// \param InsertPos Insert position in the FoldingSetVector, must have been
   ///        retrieved by an earlier call to findSpecialization().
   void addSpecialization(FunctionTemplateSpecializationInfo* Info,
                          void *InsertPos);
@@ -1688,11 +1690,11 @@
 
     /// \brief The class template specializations for this class
     /// template, including explicit specializations and instantiations.
-    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
+    llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
 
     /// \brief The class template partial specializations for this class
     /// template.
-    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
+    llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
       PartialSpecializations;
 
     /// \brief The injected-class-name type for this class template.
@@ -1710,11 +1712,11 @@
   void LoadLazySpecializations();
 
   /// \brief Retrieve the set of specializations of this class template.
-  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations();
+  llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &getSpecializations();
 
   /// \brief Retrieve the set of partial specializations of this class
   /// template.
-  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
+  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
   ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=156133&r1=156132&r2=156133&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu May  3 18:49:05 2012
@@ -145,7 +145,7 @@
 template <class EntryType>
 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
 RedeclarableTemplateDecl::findSpecializationImpl(
-                                 llvm::FoldingSet<EntryType> &Specs,
+                                 llvm::FoldingSetVector<EntryType> &Specs,
                                  const TemplateArgument *Args, unsigned NumArgs,
                                  void *&InsertPos) {
   typedef SpecEntryTraits<EntryType> SETraits;
@@ -298,13 +298,13 @@
   }
 }
 
-llvm::FoldingSet<ClassTemplateSpecializationDecl> &
+llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
 ClassTemplateDecl::getSpecializations() {
   LoadLazySpecializations();
   return getCommonPtr()->Specializations;
 }  
 
-llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
+llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
 ClassTemplateDecl::getPartialSpecializations() {
   LoadLazySpecializations();
   return getCommonPtr()->PartialSpecializations;
@@ -363,11 +363,11 @@
 
 void ClassTemplateDecl::getPartialSpecializations(
           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
-  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
+  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
     = getPartialSpecializations();
   PS.clear();
   PS.resize(PartialSpecs.size());
-  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+  for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
        P != PEnd; ++P) {
     assert(!PS[P->getSequenceNumber()]);
@@ -378,7 +378,8 @@
 ClassTemplatePartialSpecializationDecl *
 ClassTemplateDecl::findPartialSpecialization(QualType T) {
   ASTContext &Context = getASTContext();
-  typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+  using llvm::FoldingSetVector;
+  typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
     partial_spec_iterator;
   for (partial_spec_iterator P = getPartialSpecializations().begin(),
                           PEnd = getPartialSpecializations().end();
@@ -394,7 +395,7 @@
 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
                                     ClassTemplatePartialSpecializationDecl *D) {
   Decl *DCanon = D->getCanonicalDecl();
-  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+  for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
             P = getPartialSpecializations().begin(),
          PEnd = getPartialSpecializations().end();
        P != PEnd; ++P) {

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=156133&r1=156132&r2=156133&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Thu May  3 18:49:05 2012
@@ -1054,7 +1054,7 @@
   VisitRedeclarableTemplateDecl(D);
 
   if (D->isFirstDeclaration()) {
-    typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
+    typedef llvm::FoldingSetVector<ClassTemplateSpecializationDecl> CTSDSetTy;
     CTSDSetTy &CTSDSet = D->getSpecializations();
     Record.push_back(CTSDSet.size());
     for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) {
@@ -1062,7 +1062,8 @@
       Writer.AddDeclRef(&*I, Record);
     }
 
-    typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> CTPSDSetTy;
+    typedef llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
+      CTPSDSetTy;
     CTPSDSetTy &CTPSDSet = D->getPartialSpecializations();
     Record.push_back(CTPSDSet.size());
     for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) {
@@ -1146,7 +1147,7 @@
 
     // Write the function specialization declarations.
     Record.push_back(D->getSpecializations().size());
-    for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
+    for (llvm::FoldingSetVector<FunctionTemplateSpecializationInfo>::iterator
            I = D->getSpecializations().begin(),
            E = D->getSpecializations().end()   ; I != E; ++I) {
       assert(I->Function->isCanonicalDecl() &&

Added: cfe/trunk/test/CodeGenCXX/debug-info-determinism.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-determinism.cpp?rev=156133&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-determinism.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-info-determinism.cpp Thu May  3 18:49:05 2012
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -S -emit-llvm -g -o %t1.ll %s
+// RUN: %clang_cc1 -S -emit-llvm -g -o %t2.ll %s
+// RUN: diff %t1.ll %t2.ll
+
+template <int N> struct C {
+  template <int M> int f() {
+    int arr[M] = {};
+    return arr[M/2] + C<M/2>().template f<M-1>();
+  }
+};
+template <> template <> int C<0>::f<0>() { return 0; }
+template <> template <> int C<0>::f<1>() { return 0; }
+template <> template <> int C<1>::f<0>() { return 0; }
+template <> template <> int C<1>::f<1>() { return 0; }
+
+int x = C<0>().f<64>();





More information about the cfe-commits mailing list