summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2017-04-12 21:56:05 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2017-04-12 21:56:05 +0000
commit46afbbb210369c459ceafa76ae411b7f163b7ce1 (patch)
treef6d6ce5a9ae8377520e98e0bbf8f429de2c58351 /clang/lib
parent52dfe7164537321f881657fb11aa88e9fbc7ae11 (diff)
downloadbcm5719-llvm-46afbbb210369c459ceafa76ae411b7f163b7ce1.tar.gz
bcm5719-llvm-46afbbb210369c459ceafa76ae411b7f163b7ce1.zip
[modules] Delay calling DeclMustBeEmitted until it's safe.
This patch implements the suggestion in D29753 that calling DeclMustBeEmitted in the middle of deserialization should be avoided and that the actual check should be deferred until it's safe to do so. This patch fixes a crash when accessing the invalid redecl chains while trying to evaluate the value of a const VarDecl that contains a function call. Patch by Raphael Isemann (D30793)! llvm-svn: 300110
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp25
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp35
2 files changed, 32 insertions, 28 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 78f71b3efeb..406c4b50d92 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7234,31 +7234,6 @@ static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
}
-void ASTReader::PassInterestingDeclsToConsumer() {
- assert(Consumer);
-
- if (PassingDeclsToConsumer)
- return;
-
- // Guard variable to avoid recursively redoing the process of passing
- // decls to consumer.
- SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
- true);
-
- // Ensure that we've loaded all potentially-interesting declarations
- // that need to be eagerly loaded.
- for (auto ID : EagerlyDeserializedDecls)
- GetDecl(ID);
- EagerlyDeserializedDecls.clear();
-
- while (!InterestingDecls.empty()) {
- Decl *D = InterestingDecls.front();
- InterestingDecls.pop_front();
-
- PassInterestingDeclToConsumer(D);
- }
-}
-
void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
PassObjCImplDeclToConsumer(ImplD, Consumer);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 2fb882c1bec..e0304d22fe5 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3626,12 +3626,37 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// AST consumer might need to know about, queue it.
// We don't pass it to the consumer immediately because we may be in recursive
// loading, and some declarations may still be initializing.
- if (isConsumerInterestedIn(Context, D, Reader.hasPendingBody()))
- InterestingDecls.push_back(D);
+ PotentiallyInterestingDecls.push_back(
+ InterestingDecl(D, Reader.hasPendingBody()));
return D;
}
+void ASTReader::PassInterestingDeclsToConsumer() {
+ assert(Consumer);
+
+ if (PassingDeclsToConsumer)
+ return;
+
+ // Guard variable to avoid recursively redoing the process of passing
+ // decls to consumer.
+ SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
+ true);
+
+ // Ensure that we've loaded all potentially-interesting declarations
+ // that need to be eagerly loaded.
+ for (auto ID : EagerlyDeserializedDecls)
+ GetDecl(ID);
+ EagerlyDeserializedDecls.clear();
+
+ while (!PotentiallyInterestingDecls.empty()) {
+ InterestingDecl D = PotentiallyInterestingDecls.front();
+ PotentiallyInterestingDecls.pop_front();
+ if (isConsumerInterestedIn(Context, D.getDecl(), D.hasPendingBody()))
+ PassInterestingDeclToConsumer(D.getDecl());
+ }
+}
+
void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
// The declaration may have been modified by files later in the chain.
// If this is the case, read the record containing the updates from each file
@@ -3642,6 +3667,9 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
auto UpdateOffsets = std::move(UpdI->second);
DeclUpdateOffsets.erase(UpdI);
+ // FIXME: This call to isConsumerInterestedIn is not safe because
+ // we could be deserializing declarations at the moment. We should
+ // delay calling this in the same way as done in D30793.
bool WasInteresting = isConsumerInterestedIn(Context, D, false);
for (auto &FileAndOffset : UpdateOffsets) {
ModuleFile *F = FileAndOffset.first;
@@ -3663,7 +3691,8 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
// we need to hand it off to the consumer.
if (!WasInteresting &&
isConsumerInterestedIn(Context, D, Reader.hasPendingBody())) {
- InterestingDecls.push_back(D);
+ PotentiallyInterestingDecls.push_back(
+ InterestingDecl(D, Reader.hasPendingBody()));
WasInteresting = true;
}
}
OpenPOWER on IntegriCloud