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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to