[clang] cc4ec6d - [C++20] [Modules] Diagnose redeclarations from different modules

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 24 04:04:41 PDT 2024


Author: Chuanqi Xu
Date: 2024-06-24T19:03:31+08:00
New Revision: cc4ec6daf0d4f43110e8220d542c1155b8c1ef51

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

LOG: [C++20] [Modules] Diagnose redeclarations from different modules

[basic.link]/p10:

> If two declarations of an entity are attached to different modules,
> the program is ill-formed

But we only implemented the check for ODR. In this patch, we tried to
diagnose the redeclarations from different modules.

Added: 
    clang/test/Modules/same-decl-in-different-modules.cppm

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/test/Modules/no-eager-load.cppm

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f323d1c6eaf1b..134a4e4d547dd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6075,6 +6075,9 @@ def err_thread_thread_
diff erent_kind : Error<
 def err_mismatched_owning_module : Error<
   "declaration of %0 in %select{the global module|module %2}1 follows "
   "declaration in %select{the global module|module %4}3">;
+def err_multiple_decl_in_
diff erent_modules : Error<
+  "declaration %0 attached to named module '%1' can't be attached to "
+  "other modules">;
 def err_redefinition_
diff erent_type : Error<
   "redefinition of %0 with a 
diff erent type%
diff {: $ vs $|}1,2">;
 def err_redefinition_
diff erent_kind : Error<

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 4b8b515c02c70..6afb18f932e72 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3723,6 +3723,23 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
 #include "clang/AST/DeclNodes.inc"
   }
 
+  // [basic.link]/p10:
+  //    If two declarations of an entity are attached to 
diff erent modules,
+  //    the program is ill-formed;
+  //
+  // FIXME: Get rid of the enumeration of decl types once we have an appropriate
+  // abstract for decls of an entity. e.g., the namespace decl and using decl
+  // doesn't introduce an entity.
+  if (Module *M = Previous->getOwningModule();
+      M && M->isNamedModule() &&
+      isa<VarDecl, FunctionDecl, TagDecl, RedeclarableTemplateDecl>(Previous) &&
+      !Reader.getContext().isInSameModule(M, D->getOwningModule())) {
+    Reader.Diag(Previous->getLocation(),
+                diag::err_multiple_decl_in_
diff erent_modules)
+        << cast<NamedDecl>(Previous) << M->Name;
+    Reader.Diag(D->getLocation(), diag::note_also_found);
+  }
+
   // If the declaration was visible in one module, a redeclaration of it in
   // another module remains visible even if it wouldn't be visible by itself.
   //

diff  --git a/clang/test/Modules/no-eager-load.cppm b/clang/test/Modules/no-eager-load.cppm
index 8a2c7656bca2b..c9eddaaed1555 100644
--- a/clang/test/Modules/no-eager-load.cppm
+++ b/clang/test/Modules/no-eager-load.cppm
@@ -44,6 +44,9 @@ void use() {
            // expected-note@* {{but in 'a' found a 
diff erent body}}
 }
 
+// expected-error at a.cppm:* {{declaration 'foo' attached to named module 'a' can't be attached to other modules}}
+// expected-note at b.cppm:* {{}}
+
 //--- h.cppm
 export module h;
 export import a;
@@ -55,3 +58,6 @@ void use() {
     foo(); // expected-error@* {{'foo' has 
diff erent definitions in 
diff erent modules;}}
            // expected-note@* {{but in 'a' found a 
diff erent body}}
 }
+
+// expected-error at a.cppm:* {{declaration 'foo' attached to named module 'a' can't be attached to other modules}}
+// expected-note at b.cppm:* {{}}

diff  --git a/clang/test/Modules/same-decl-in-
diff erent-modules.cppm b/clang/test/Modules/same-decl-in-
diff erent-modules.cppm
new file mode 100644
index 0000000000000..2e8e90f7cd8e9
--- /dev/null
+++ b/clang/test/Modules/same-decl-in-
diff erent-modules.cppm
@@ -0,0 +1,42 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o %t/mod1.pcm
+// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -emit-module-interface -o %t/mod2.pcm
+// RUN: %clang_cc1 -std=c++20 %t/test.cc -fprebuilt-module-path=%t -fsyntax-only -verify
+
+//--- mod1.cppm
+export module mod1;
+export int v;
+export void func();
+export class A {};
+export template <class C>
+struct S {};
+
+//--- mod2.cppm
+export module mod2;
+export int v;
+export void func();
+export class A;
+export template <class C>
+struct S {};
+
+//--- test.cc
+import mod1;
+import mod2;
+void test() {
+    int value = v;
+    func();
+    A a;
+    S<int> s;
+}
+
+// expected-error at mod1.cppm:* {{declaration 'v' attached to named module 'mod1' can't be attached to other modules}}
+// expected-note at mod2.cppm:* {{}}
+// expected-error at mod1.cppm:* {{declaration 'func' attached to named module 'mod1' can't be attached to other modules}}
+// expected-note at mod2.cppm:* {{}}
+// expected-error at mod1.cppm:* {{declaration 'A' attached to named module 'mod1' can't be attached to other modules}}
+// expected-note at mod2.cppm:* {{}}
+// expected-error at mod1.cppm:* 1+{{declaration 'S' attached to named module 'mod1' can't be attached to other modules}}
+// expected-note at mod2.cppm:* 1+{{}}


        


More information about the cfe-commits mailing list