[clang] c50a4b3 - [Modules] Incorrect ODR detection for unresolved using type

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 16 18:38:28 PST 2021


Author: Chuanqi Xu
Date: 2021-12-17T10:37:40+08:00
New Revision: c50a4b3f97497c27ad62797080b52f501dac5e38

URL: https://github.com/llvm/llvm-project/commit/c50a4b3f97497c27ad62797080b52f501dac5e38
DIFF: https://github.com/llvm/llvm-project/commit/c50a4b3f97497c27ad62797080b52f501dac5e38.diff

LOG: [Modules] Incorrect ODR detection for unresolved using type

Implement `getUnresolvedUsingType()` and don't create a new
`UnresolvedUsingType` when there is already canonical declaration.

This solved an incorrect ODR detection in modules for uresolved using
type.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D115792

Added: 
    clang/test/Modules/Inputs/odr_using_dependent_name/X.cppm
    clang/test/Modules/Inputs/odr_using_dependent_name/foo.h
    clang/test/Modules/odr_using_dependent_name.cppm

Modified: 
    clang/include/clang/AST/ASTContext.h
    clang/include/clang/AST/TypeProperties.td
    clang/lib/AST/ASTContext.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index e861cd6ae3466..ebe8fc8faf910 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1564,6 +1564,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
 
   QualType getEnumType(const EnumDecl *Decl) const;
 
+  QualType
+  getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
+
   QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
 
   QualType getAttributedType(attr::Kind attrKind,

diff  --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index b7730a0f32dcf..19325d0c1fb23 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -358,7 +358,7 @@ let Class = UnresolvedUsingType in {
   }
 
   def : Creator<[{
-    return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
+    return ctx.getUnresolvedUsingType(cast<UnresolvedUsingTypenameDecl>(declaration));
   }]>;
 }
 

diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b6e1966bf980c..22020119b9f50 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4568,9 +4568,7 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
     assert(Enum->isFirstDecl() && "enum has previous declaration");
     return getEnumType(Enum);
   } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
-    Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using);
-    Decl->TypeForDecl = newType;
-    Types.push_back(newType);
+    return getUnresolvedUsingType(Using);
   } else
     llvm_unreachable("TypeDecl without a type?");
 
@@ -4619,6 +4617,22 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
   return QualType(newType, 0);
 }
 
+QualType ASTContext::getUnresolvedUsingType(
+    const UnresolvedUsingTypenameDecl *Decl) const {
+  if (Decl->TypeForDecl)
+    return QualType(Decl->TypeForDecl, 0);
+
+  if (const UnresolvedUsingTypenameDecl *CanonicalDecl =
+          Decl->getCanonicalDecl())
+    if (CanonicalDecl->TypeForDecl)
+      return QualType(Decl->TypeForDecl = CanonicalDecl->TypeForDecl, 0);
+
+  Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Decl);
+  Decl->TypeForDecl = newType;
+  Types.push_back(newType);
+  return QualType(newType, 0);
+}
+
 QualType ASTContext::getAttributedType(attr::Kind attrKind,
                                        QualType modifiedType,
                                        QualType equivalentType) {

diff  --git a/clang/test/Modules/Inputs/odr_using_dependent_name/X.cppm b/clang/test/Modules/Inputs/odr_using_dependent_name/X.cppm
new file mode 100644
index 0000000000000..ccf246017a497
--- /dev/null
+++ b/clang/test/Modules/Inputs/odr_using_dependent_name/X.cppm
@@ -0,0 +1,3 @@
+module;
+#include "foo.h"
+export module X;

diff  --git a/clang/test/Modules/Inputs/odr_using_dependent_name/foo.h b/clang/test/Modules/Inputs/odr_using_dependent_name/foo.h
new file mode 100644
index 0000000000000..2c02912b2257e
--- /dev/null
+++ b/clang/test/Modules/Inputs/odr_using_dependent_name/foo.h
@@ -0,0 +1,9 @@
+template <class T>
+struct bar {
+  using Ty = int;
+};
+template <class T>
+struct foo : public bar<T> {
+  using typename bar<T>::Ty;
+  void baz(Ty);
+};

diff  --git a/clang/test/Modules/odr_using_dependent_name.cppm b/clang/test/Modules/odr_using_dependent_name.cppm
new file mode 100644
index 0000000000000..8d7ea9f57bedc
--- /dev/null
+++ b/clang/test/Modules/odr_using_dependent_name.cppm
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: %clang -std=c++20 %S/Inputs/odr_using_dependent_name/X.cppm --precompile -o %t/X.pcm
+// RUN: %clang -std=c++20 -I%S/Inputs/odr_using_dependent_name -fprebuilt-module-path=%t %s --precompile -c
+// expected-no-diagnostics
+module;
+#include "foo.h"
+export module Y;
+import X;


        


More information about the cfe-commits mailing list