[PATCH][Modules][PR26179]

Vassil Vassilev via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 16 15:43:37 PST 2016


Hi,
   Could somebody review the attached patch. It fixes 
https://llvm.org/bugs/show_bug.cgi?id=26179
Many thanks!
Vassil

-------------- next part --------------
From 947a163ab4e13c44625085dd51faa656b72de3ac Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev at gmail.com>
Date: Sat, 16 Jan 2016 23:52:40 +0100
Subject: [PATCH] [modules] Teach clang to how to merge variable redecls with
 different types.

We can get decls with different types on the redecl chain. Eg.
template <typename T> struct S {
  static T Var[]; // #1
};
template <typename T> T S<T>::Var[sizeof(T)]; // #2
Trying to compare #1 and #2 should go through their canonical decls.

Fixes https://llvm.org/bugs/show_bug.cgi?id=26179
---
 lib/Serialization/ASTReaderDecl.cpp          | 17 +++++++++++++++--
 test/Modules/Inputs/PR26179/A.h              |  2 ++
 test/Modules/Inputs/PR26179/B.h              |  1 +
 test/Modules/Inputs/PR26179/basic_string.h   | 12 ++++++++++++
 test/Modules/Inputs/PR26179/module.modulemap |  9 +++++++++
 test/Modules/pr26179.cpp                     |  7 +++++++
 6 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 test/Modules/Inputs/PR26179/A.h
 create mode 100644 test/Modules/Inputs/PR26179/B.h
 create mode 100644 test/Modules/Inputs/PR26179/basic_string.h
 create mode 100644 test/Modules/Inputs/PR26179/module.modulemap
 create mode 100644 test/Modules/pr26179.cpp

diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 5bf95f8..b68b7fe 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -2595,8 +2595,21 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
   // Variables with the same type and linkage match.
   if (VarDecl *VarX = dyn_cast<VarDecl>(X)) {
     VarDecl *VarY = cast<VarDecl>(Y);
-    return (VarX->getLinkageInternal() == VarY->getLinkageInternal()) &&
-      VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType());
+    if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) {
+      ASTContext &Context = VarX->getASTContext();
+      if (Context.hasSameType(VarX->getType(), VarY->getType()))
+        return true;
+
+      // We can get decls with different types on the redecl chain. Eg.
+      // template <typename T> struct S { static T Var[]; }; // #1
+      // template <typename T> T S<T>::Var[sizeof(T)]; // #2
+      // Trying to compare #1 and #2 should go through their canonical decls.
+      QualType VarXTy = VarX->getCanonicalDecl()->getType();
+      QualType VarYTy = VarY->getCanonicalDecl()->getType();
+      if (Context.hasSameType(VarXTy, VarYTy))
+        return true;
+    }
+    return false;
   }
 
   // Namespaces with the same name and inlinedness match.
diff --git a/test/Modules/Inputs/PR26179/A.h b/test/Modules/Inputs/PR26179/A.h
new file mode 100644
index 0000000..c264f4c
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/A.h
@@ -0,0 +1,2 @@
+#include "basic_string.h"
+#include "B.h"
diff --git a/test/Modules/Inputs/PR26179/B.h b/test/Modules/Inputs/PR26179/B.h
new file mode 100644
index 0000000..46a109e
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/B.h
@@ -0,0 +1 @@
+#include "basic_string.h"
diff --git a/test/Modules/Inputs/PR26179/basic_string.h b/test/Modules/Inputs/PR26179/basic_string.h
new file mode 100644
index 0000000..653ce07
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/basic_string.h
@@ -0,0 +1,12 @@
+#ifndef _GLIBCXX_STRING
+#define _GLIBCXX_STRING 1
+
+template<typename T>
+struct basic_string {
+  static T _S_empty_rep_storage[];
+};
+
+template<typename T>
+T basic_string<T>::_S_empty_rep_storage[sizeof(T)];
+
+#endif
diff --git a/test/Modules/Inputs/PR26179/module.modulemap b/test/Modules/Inputs/PR26179/module.modulemap
new file mode 100644
index 0000000..4937418
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/module.modulemap
@@ -0,0 +1,9 @@
+module A {
+  header "A.h"
+  export *
+}
+
+module B {
+  header "B.h"
+  export *
+}
diff --git a/test/Modules/pr26179.cpp b/test/Modules/pr26179.cpp
new file mode 100644
index 0000000..f25f1ce
--- /dev/null
+++ b/test/Modules/pr26179.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/PR26179 -verify %s
+// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/PR26179/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR26179 -verify %s
+
+#include "A.h"
+
+// expected-no-diagnostics
-- 
2.3.8 (Apple Git-58)



More information about the cfe-commits mailing list