diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index bee71cf296ac3..05ac5e2e679e7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -650,6 +650,9 @@ Improvements to Clang's diagnostics #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490, #GH36703, #GH32903, #GH23312, #GH69874. +- A warning is now emitted when ``main`` is attached to a named module, + which can be turned off with ``-Wno-main-attached-to-named-module``. (#GH146247) + - Clang now avoids issuing `-Wreturn-type` warnings in some cases where the final statement of a non-void function is a `throw` expression, or a call to a function that is trivially known to always throw (i.e., its diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5062505cf3c01..451619709c087 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1062,6 +1062,10 @@ def err_constexpr_main : Error< "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; +def warn_main_in_named_module + : ExtWarn<"'main' should not be attached to a named module; consider " + "adding C++ language linkage">, + InGroup>; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 58b475929cc4f..33b9ef869746a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12489,6 +12489,14 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) { : FixItHint()); FD->setInvalidDecl(true); } + + // In C++ [basic.start.main]p3, it is said a program attaching main to a + // named module is ill-formed. + if (FD->isInNamedModule()) { + const SourceLocation start = FD->getTypeSpecStartLoc(); + Diag(start, diag::warn_main_in_named_module) + << FixItHint::CreateInsertion(start, "extern \"C++\" ", true); + } } // Treat protoless main() as nullary. diff --git a/clang/test/SemaCXX/modules.cppm b/clang/test/SemaCXX/modules.cppm index 5d0d6da44a2ed..81bc749c58259 100644 --- a/clang/test/SemaCXX/modules.cppm +++ b/clang/test/SemaCXX/modules.cppm @@ -68,6 +68,8 @@ int n; //--- test3.cpp export module bar; +int main() {} // expected-warning {{'main' should not be attached to a named module; consider adding C++ language linkage}} + static int m; int n;