diff options
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 20 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR26179/A.h | 4 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR26179/B.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR26179/basic_string.h | 14 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR26179/module.modulemap | 9 | ||||
-rw-r--r-- | clang/test/Modules/pr26179.cpp | 7 |
6 files changed, 54 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 5bf95f878d4..9bcd9a01649 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2595,8 +2595,24 @@ 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 &C = VarX->getASTContext(); + if (C.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 + // Only? happens when completing an incomplete array type. In this case + // when comparing #1 and #2 we should go through their elements types. + const ArrayType *VarXTy = C.getAsArrayType(VarX->getType()); + const ArrayType *VarYTy = C.getAsArrayType(VarY->getType()); + if (!VarXTy || !VarYTy) + return false; + if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType()) + return C.hasSameType(VarXTy->getElementType(), VarYTy->getElementType()); + } + return false; } // Namespaces with the same name and inlinedness match. diff --git a/clang/test/Modules/Inputs/PR26179/A.h b/clang/test/Modules/Inputs/PR26179/A.h new file mode 100644 index 00000000000..ce95fafb4bf --- /dev/null +++ b/clang/test/Modules/Inputs/PR26179/A.h @@ -0,0 +1,4 @@ +#include "basic_string.h" +#include "B.h" + +int *p = a; diff --git a/clang/test/Modules/Inputs/PR26179/B.h b/clang/test/Modules/Inputs/PR26179/B.h new file mode 100644 index 00000000000..eb8d1c29e79 --- /dev/null +++ b/clang/test/Modules/Inputs/PR26179/B.h @@ -0,0 +1,2 @@ +#include "basic_string.h" +extern int a[5]; diff --git a/clang/test/Modules/Inputs/PR26179/basic_string.h b/clang/test/Modules/Inputs/PR26179/basic_string.h new file mode 100644 index 00000000000..afd1e0d3b34 --- /dev/null +++ b/clang/test/Modules/Inputs/PR26179/basic_string.h @@ -0,0 +1,14 @@ +#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)]; + +extern int a[]; + +#endif diff --git a/clang/test/Modules/Inputs/PR26179/module.modulemap b/clang/test/Modules/Inputs/PR26179/module.modulemap new file mode 100644 index 00000000000..49374181d75 --- /dev/null +++ b/clang/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/clang/test/Modules/pr26179.cpp b/clang/test/Modules/pr26179.cpp new file mode 100644 index 00000000000..f25f1ce24bd --- /dev/null +++ b/clang/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 |