[C++20][Modules] Handle defaulted and deleted functions in header units.
authorIain Sandoe <iain@sandoe.co.uk>
Tue, 17 Jan 2023 10:17:08 +0000 (10:17 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Sat, 21 Jan 2023 12:55:52 +0000 (12:55 +0000)
Address part of https://github.com/llvm/llvm-project/issues/60079.

Deleted and Defaulted functions are implicitly inline, but that state
is not set at the point that we perform the diagnostic checks for externally-
visible non-inline functions; check the function body type explicitly in the
diagnostic.

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

clang/lib/Sema/SemaDecl.cpp
clang/test/CXX/module/module.import/p6.cpp

index 3ae3e33..e2b921b 100644 (file)
@@ -15254,9 +15254,15 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-      FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+      FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+      !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+      BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+    assert(FD->isThisDeclarationADefinition());
     Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
     FD->setInvalidDecl();
   }
index 7d86327..4360d3e 100644 (file)
@@ -28,3 +28,11 @@ public:
     static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;