[PATCH] D156063: [Clang] Reject programs declaring namespace std to be inline
PoYao Chang via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 24 10:31:54 PDT 2023
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbed75faf7d76: [Clang] Reject programs declaring namespace std to be inline (authored by rZhBoYao).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D156063/new/
https://reviews.llvm.org/D156063
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
+++ clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
// FIXME: We should probably suppress the warning on reopening an inline
// namespace without the inline keyword if it's not the first opening of the
@@ -16,3 +16,11 @@
inline namespace {} // expected-note {{previous definition}}
namespace {} // expected-warning {{inline namespace reopened as a non-inline namespace}}
}
+
+namespace std {}
+inline namespace std {} // expected-error{{cannot declare the namespace 'std' to be inline}}
+inline namespace std::foo {} // expected-error{{cannot declare the namespace 'std' to be inline}}
+ // expected-error at -1{{nested namespace definition cannot be 'inline'}}
+namespace foo::inline std {} // expected-note {{previous definition}}
+namespace foo { inline namespace std {} } // OK
+namespace foo { namespace std {} } // expected-warning {{inline namespace reopened as a non-inline namespace}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -11388,6 +11388,20 @@
NamespaceDecl *PrevNS = nullptr;
if (II) {
+ // C++ [namespace.std]p7:
+ // A translation unit shall not declare namespace std to be an inline
+ // namespace (9.8.2).
+ //
+ // Precondition: the std namespace is in the file scope and is declared to
+ // be inline
+ auto DiagnoseInlineStdNS = [&]() {
+ assert(IsInline && II->isStr("std") &&
+ CurContext->getRedeclContext()->isTranslationUnit() &&
+ "Precondition of DiagnoseInlineStdNS not met");
+ Diag(InlineLoc, diag::err_inline_namespace_std)
+ << SourceRange(InlineLoc, InlineLoc.getLocWithOffset(6));
+ IsInline = false;
+ };
// C++ [namespace.def]p2:
// The identifier in an original-namespace-definition shall not
// have been previously defined in the declarative region in
@@ -11408,7 +11422,10 @@
if (PrevNS) {
// This is an extended namespace definition.
- if (IsInline != PrevNS->isInline())
+ if (IsInline && II->isStr("std") &&
+ CurContext->getRedeclContext()->isTranslationUnit())
+ DiagnoseInlineStdNS();
+ else if (IsInline != PrevNS->isInline())
DiagnoseNamespaceInlineMismatch(*this, NamespaceLoc, Loc, II,
&IsInline, PrevNS);
} else if (PrevDecl) {
@@ -11420,6 +11437,8 @@
// Continue on to push Namespc as current DeclContext and return it.
} else if (II->isStr("std") &&
CurContext->getRedeclContext()->isTranslationUnit()) {
+ if (IsInline)
+ DiagnoseInlineStdNS();
// This is the first "real" definition of the namespace "std", so update
// our cache of the "std" namespace to point at this definition.
PrevNS = getStdNamespace();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1579,6 +1579,8 @@
InGroup<InlineNamespaceReopenedNoninline>;
def err_inline_namespace_mismatch : Error<
"non-inline namespace cannot be reopened as inline">;
+def err_inline_namespace_std : Error<
+ "cannot declare the namespace 'std' to be inline">;
def err_unexpected_friend : Error<
"friends can only be classes or functions">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -84,6 +84,7 @@
directly rather than instantiating the definition from the standard library.
- Implemented `CWG2518 <https://wg21.link/CWG2518>`_ which allows ``static_assert(false)``
to not be ill-formed when its condition is evaluated in the context of a template definition.
+- Declaring namespace std to be an inline namespace is now prohibited, `[namespace.std]p7`.
C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156063.543627.patch
Type: text/x-patch
Size: 4417 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230724/303ebf47/attachment-0001.bin>
More information about the cfe-commits
mailing list