[clang] 12ae1ea - [C++20][Modules] Relax ODR check in unnamed modules (#111160)

via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 10 00:49:42 PDT 2024


Author: Dmitry Polukhin
Date: 2024-10-10T08:49:39+01:00
New Revision: 12ae1ea13e68657ac75d65fd62385cae5272e2cb

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

LOG: [C++20][Modules] Relax ODR check in unnamed modules (#111160)

Summary:
Option `-fskip-odr-check-in-gmf` is set by default and I think it is
what most of C++ developers want. But in header units, Clang ODR
checking is too strict, making them hard to use, as seen in the example
in the diff. This diff relaxes ODR checks for unnamed modules to match
GMF ODR checking.

Test Plan: check-clang

Added: 
    clang/test/Headers/header-unit-common-cmp-cat.cpp

Modified: 
    clang/include/clang/AST/DeclBase.h
    clang/include/clang/Serialization/ASTReader.h
    clang/lib/AST/DeclBase.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index ee662ed73d7e0e..a3447d19909752 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -687,6 +687,9 @@ class alignas(8) Decl {
   /// Whether this declaration comes from a named module.
   bool isInNamedModule() const;
 
+  /// Whether this declaration comes from a header unit.
+  bool isFromHeaderUnit() const;
+
   /// Return true if this declaration has an attribute which acts as
   /// definition of the entity, such as 'alias' or 'ifunc'.
   bool hasDefiningAttr() const;

diff  --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index aa88560b259a3b..ee4e897b248882 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2527,7 +2527,7 @@ class BitsUnpacker {
 
 inline bool shouldSkipCheckingODR(const Decl *D) {
   return D->getASTContext().getLangOpts().SkipODRCheckInGMF &&
-         D->isFromGlobalModule();
+         (D->isFromGlobalModule() || D->isFromHeaderUnit());
 }
 
 } // namespace clang

diff  --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index f42857f20efc44..48b91dca1f6d91 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1168,6 +1168,10 @@ bool Decl::isInNamedModule() const {
   return getOwningModule() && getOwningModule()->isNamedModule();
 }
 
+bool Decl::isFromHeaderUnit() const {
+  return getOwningModule() && getOwningModule()->isHeaderUnit();
+}
+
 static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
 static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
 

diff  --git a/clang/test/Headers/header-unit-common-cmp-cat.cpp b/clang/test/Headers/header-unit-common-cmp-cat.cpp
new file mode 100644
index 00000000000000..faeb3ec32127f5
--- /dev/null
+++ b/clang/test/Headers/header-unit-common-cmp-cat.cpp
@@ -0,0 +1,40 @@
+// RUN: rm -fR %t
+// RUN: split-file %s %t
+// RUN: cd %t
+// RUN: %clang_cc1 -verify -std=c++20 -fskip-odr-check-in-gmf -I. -emit-header-unit -xc++-user-header bz1.h
+// RUN: %clang_cc1 -verify -std=c++20 -fskip-odr-check-in-gmf -I. -emit-header-unit -xc++-user-header bz2.h
+// RUN: %clang_cc1 -verify -std=c++20 -fskip-odr-check-in-gmf -I. -emit-header-unit -xc++-user-header -fmodule-file=bz1.pcm -fmodule-file=bz2.pcm bz.cpp
+
+//--- compare
+namespace std {
+namespace __detail {
+
+template<typename _Tp>
+inline constexpr unsigned __cmp_cat_id = 1;
+
+template<typename... _Ts>
+constexpr auto __common_cmp_cat() {
+  (__cmp_cat_id<_Ts> | ...);
+}
+
+} // namespace __detail
+} // namespace std
+
+//--- bz0.h
+template <class T>
+int operator|(T, T);
+
+//--- bz1.h
+#include "bz0.h"
+#include <compare>
+// expected-no-diagnostics
+
+//--- bz2.h
+#include <compare>
+// expected-no-diagnostics
+
+//--- bz.cpp
+#include <compare>
+
+import "bz1.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
+import "bz2.h"; // expected-warning {{the implementation of header units is in an experimental phase}}


        


More information about the cfe-commits mailing list