[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