elsteveogrande updated this revision to Diff 166130.
elsteveogrande added a comment.
rebase atop https://reviews.llvm.org/D50948 (correctly this time) to exclude
those changes
Repository:
rC Clang
https://reviews.llvm.org/D50949
Files:
include/clang/AST/LambdaCapture.h
lib/Serialization/ASTReaderDecl.cpp
test/Modules/merge-lambdas.cpp
Index: test/Modules/merge-lambdas.cpp
===================================================================
--- test/Modules/merge-lambdas.cpp
+++ test/Modules/merge-lambdas.cpp
@@ -49,3 +49,25 @@
#pragma clang module import A
void (*p)() = f<int>();
+
+#pragma clang module build PR38531
+module PR38531 {}
+#pragma clang module contents
+#pragma clang module begin PR38531
+template <typename>
+struct S {};
+struct Fun {
+ template <typename F, typename T=decltype(S<F>())>
+ Fun(F) {}
+};
+template <typename>
+void foo(Fun=[]{}) {}
+struct T {
+ void func() {
+ foo<void>();
+ }
+};
+#pragma clang module end
+#pragma clang module endbuild
+#pragma clang module import PR38531
+S<void> s;
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1761,8 +1761,6 @@
PFDI->second == ASTReader::PendingFakeDefinitionKind::Fake) {
// We faked up this definition data because we found a class for which we'd
// not yet loaded the definition. Replace it with the real thing now.
- assert(!DD.hasLambdaData() && !MergeDD.hasLambdaData() &&
- "faked up lambda definition?");
PFDI->second = ASTReader::PendingFakeDefinitionKind::FakeLoaded;
// Don't change which declaration is the definition; that is required
@@ -1845,9 +1843,41 @@
// FIXME: Issue a diagnostic if FirstFriend doesn't match when we come to
// lazily load it.
- if (DD.hasLambdaData()) {
- // FIXME: ODR-checking for merging lambdas (this happens, for instance,
- // when they occur within the body of a function template specialization).
+ assert (DD.hasLambdaData() == MergeDD.hasLambdaData() &&
+ "Merging definitions, one of which is a lambda, the other not?");
+ if (DD.hasLambdaData() && MergeDD.hasLambdaData()) {
+ auto &LDD = *DD.LambdaData;
+ auto &MergeLDD = *MergeDD.LambdaData;
+
+#define MATCH_LAM_FIELD(Field) \
+ DetectedOdrViolation |= LDD.Field != MergeLDD.Field;
+ MATCH_LAM_FIELD(Dependent)
+ MATCH_LAM_FIELD(IsGenericLambda)
+ MATCH_LAM_FIELD(CaptureDefault)
+ MATCH_LAM_FIELD(NumCaptures)
+ MATCH_LAM_FIELD(NumExplicitCaptures)
+ MATCH_LAM_FIELD(ManglingNumber)
+#undef MATCH_LAM_FIELD
+
+ auto *C1 = LDD.Captures;
+ auto *C2 = MergeLDD.Captures;
+ for (int I = 0; !DetectedOdrViolation && I < LDD.NumCaptures; ++I) {
+ if (C1[I] != C2[I]) {
+ DetectedOdrViolation = true;
+ }
+ }
+
+ if (LDD.MethodTyInfo || MergeLDD.MethodTyInfo) {
+ if (!LDD.MethodTyInfo ||
+ !MergeLDD.MethodTyInfo ||
+ (LDD.MethodTyInfo->getType().getTypePtrOrNull() !=
+ MergeLDD.MethodTyInfo->getType().getTypePtrOrNull())) {
+ DetectedOdrViolation = true;
+ }
+ }
+
+ // FIXME: Issue a diagnostic if ContextDecl doesn't match when we come to
+ // lazily load it.
}
if (D->getODRHash() != MergeDD.ODRHash) {
Index: include/clang/AST/LambdaCapture.h
===================================================================
--- include/clang/AST/LambdaCapture.h
+++ include/clang/AST/LambdaCapture.h
@@ -135,6 +135,16 @@
assert(isPackExpansion() && "No ellipsis location for a non-expansion");
return EllipsisLoc;
}
+
+ // [In]Equality operators -- primarily for ODR-compliance checking.
+
+ bool operator==(LambdaCapture const &RHS) const {
+ return DeclAndBits == RHS.DeclAndBits;
+ }
+
+ bool operator!=(LambdaCapture const &RHS) const {
+ return !operator==(RHS);
+ }
};
} // end namespace clang
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits