From: Richard Smith Date: Wed, 11 Mar 2015 00:00:51 +0000 (+0000) Subject: [modules] Fix iterator invalidation issue with names being added to a module X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=532ae572bbe1d2239646c728cd2d5db753430ad3;p=clang [modules] Fix iterator invalidation issue with names being added to a module while we're writing out the identifier table. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231890 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 2e8e590eb5..3f8db194d0 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -4428,16 +4428,19 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, // Make sure all decls associated with an identifier are registered for // serialization. + llvm::SmallVector IIsToVisit; for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), IDEnd = PP.getIdentifierTable().end(); ID != IDEnd; ++ID) { const IdentifierInfo *II = ID->second; - if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) { - for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), - DEnd = SemaRef.IdResolver.end(); - D != DEnd; ++D) { - GetDeclRef(*D); - } + if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) + IIsToVisit.push_back(II); + } + for (const IdentifierInfo *II : IIsToVisit) { + for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), + DEnd = SemaRef.IdResolver.end(); + D != DEnd; ++D) { + GetDeclRef(*D); } } diff --git a/test/Modules/Inputs/invalidate-identifiers/a.h b/test/Modules/Inputs/invalidate-identifiers/a.h new file mode 100644 index 0000000000..16fe9edcf4 --- /dev/null +++ b/test/Modules/Inputs/invalidate-identifiers/a.h @@ -0,0 +1,17 @@ +// Ensure that loading 'i' introduces enough identifiers to cause the +// identifier table to be reallocated. +#define TYPEDEFS(x) typedef x##0 x; typedef x##1 x; +#define DEPTH_0(x) DEPTH_1(x##0) DEPTH_1(x##1) TYPEDEFS(x) +#define DEPTH_1(x) DEPTH_2(x##0) DEPTH_2(x##1) TYPEDEFS(x) +#define DEPTH_2(x) DEPTH_3(x##0) DEPTH_3(x##1) TYPEDEFS(x) +#define DEPTH_3(x) DEPTH_4(x##0) DEPTH_4(x##1) TYPEDEFS(x) +#define DEPTH_4(x) DEPTH_5(x##0) DEPTH_5(x##1) TYPEDEFS(x) +#define DEPTH_5(x) DEPTH_6(x##0) DEPTH_6(x##1) TYPEDEFS(x) +#define DEPTH_6(x) DEPTH_7(x##0) DEPTH_7(x##1) TYPEDEFS(x) +#define DEPTH_7(x) DEPTH_8(x##0) DEPTH_8(x##1) TYPEDEFS(x) +#define DEPTH_8(x) DEPTH_9(x##0) DEPTH_9(x##1) TYPEDEFS(x) +#define DEPTH_9(x) DEPTH_A(x##0) DEPTH_A(x##1) TYPEDEFS(x) +#define DEPTH_A(x) DEPTH_B(x##0) DEPTH_B(x##1) TYPEDEFS(x) +#define DEPTH_B(x) typedef int x; +DEPTH_0(i) +extern i v; diff --git a/test/Modules/Inputs/invalidate-identifiers/b.h b/test/Modules/Inputs/invalidate-identifiers/b.h new file mode 100644 index 0000000000..2af246dc77 --- /dev/null +++ b/test/Modules/Inputs/invalidate-identifiers/b.h @@ -0,0 +1,2 @@ +extern int v; +#include "a.h" diff --git a/test/Modules/Inputs/invalidate-identifiers/module.modulemap b/test/Modules/Inputs/invalidate-identifiers/module.modulemap new file mode 100644 index 0000000000..a36568207b --- /dev/null +++ b/test/Modules/Inputs/invalidate-identifiers/module.modulemap @@ -0,0 +1,2 @@ +module a { header "a.h" } +module b { header "b.h" } diff --git a/test/Modules/invalidate-identifiers.c b/test/Modules/invalidate-identifiers.c new file mode 100644 index 0000000000..de3aa10db4 --- /dev/null +++ b/test/Modules/invalidate-identifiers.c @@ -0,0 +1,4 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/invalidate-identifiers -emit-llvm-only %s + +#include "b.h"