[PATCH] D43494: [Modules] Fix creating fake definition data for lambdas.
Volodymyr Sapsai via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 19 16:45:29 PST 2018
vsapsai created this revision.
vsapsai added reviewers: rsmith, bruno.
Herald added a subscriber: jkorous-apple.
During reading C++ definition data for lambda we can access
CXXRecordDecl representing lambda before we finished reading the
definition data. This can happen by reading a captured variable which is
VarDecl, then reading its decl context which is CXXMethodDecl `operator()`,
then trying to merge redeclarable methods and accessing
enclosing CXXRecordDecl. The call stack looks roughly like
VisitCXXRecordDecl
ReadCXXRecordDefinition
VisitVarDecl
VisitCXXMethodDecl
mergeRedeclarable
getPrimaryContextForMerging
If we add fake definition data at this point, later we'll hit the assertion
Assertion failed: (!DD.IsLambda && !MergeDD.IsLambda && "faked up lambda definition?"), function MergeDefinitionData, file clang/lib/Serialization/ASTReaderDecl.cpp, line 1675.
The fix is to check if we are still reading real definition data and to
avoid adding a fake one in this case. Fixes PR32556.
rdar://problem/37461072
https://reviews.llvm.org/D43494
Files:
clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/Modules/Inputs/self-referencing-lambda/a.h
clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
clang/test/Modules/self-referencing-lambda.cpp
Index: clang/test/Modules/self-referencing-lambda.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/self-referencing-lambda.cpp
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/self-referencing-lambda %s -verify -emit-obj -o %t2.o
+// expected-no-diagnostics
+
+#include "a.h"
Index: clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
@@ -0,0 +1,4 @@
+module "a.h" {
+ header "a.h"
+ export *
+}
Index: clang/test/Modules/Inputs/self-referencing-lambda/a.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/self-referencing-lambda/a.h
@@ -0,0 +1,4 @@
+void f() {
+ int x = 0;
+ auto q = [xm = x]{};
+}
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1782,7 +1782,10 @@
else
DD = new (C) struct CXXRecordDecl::DefinitionData(D);
+ assert(!D->IsBeingDefined && "Should not overwrite definition in progress");
+ D->IsBeingDefined = true;
ReadCXXDefinitionData(*DD, D);
+ D->IsBeingDefined = false;
// We might already have a definition for this record. This can happen either
// because we're reading an update record, or because we've already done some
@@ -2963,6 +2966,9 @@
if (!DD)
DD = RD->getCanonicalDecl()->DefinitionData;
+ if (!DD && RD->isBeingDefined())
+ return nullptr;
+
// If there's no definition yet, then DC's definition is added by an update
// record, but we've not yet loaded that update record. In this case, we
// commit to DC being the canonical definition now, and will fix this when
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43494.134991.patch
Type: text/x-patch
Size: 2002 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180220/549dcfc7/attachment.bin>
More information about the cfe-commits
mailing list