diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 84106856ca76..d96b40ac7eef 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -502,6 +502,8 @@ def err_static_assert_expression_is_not_constant : Error< "static_assert expression is not an integral constant expression">; def err_static_assert_failed : Error<"static_assert failed \"%0\"">; +def warn_inline_namespace_reopened_noninline : Warning< + "inline namespace cannot be re-opened as a non-inline namespace">; def err_inline_namespace_mismatch : Error< "%select{|non-}0inline namespace " "cannot be reopened as %select{non-|}0inline">; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c6a0490c2472..90c840ba7faa 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4657,10 +4657,18 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, // This is an extended namespace definition. if (Namespc->isInline() != OrigNS->isInline()) { // inline-ness must match - Diag(Namespc->getLocation(), diag::err_inline_namespace_mismatch) - << Namespc->isInline(); + if (OrigNS->isInline()) { + // The user probably just forgot the 'inline', so suggest that it + // be added back. + Diag(Namespc->getLocation(), + diag::warn_inline_namespace_reopened_noninline) + << FixItHint::CreateInsertion(NamespaceLoc, "inline "); + } else { + Diag(Namespc->getLocation(), diag::err_inline_namespace_mismatch) + << Namespc->isInline(); + } Diag(OrigNS->getLocation(), diag::note_previous_definition); - Namespc->setInvalidDecl(); + // Recover by ignoring the new namespace's inline status. Namespc->setInline(OrigNS->isInline()); } diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp index 198b0135187e..e3d3d683ceb7 100644 --- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp @@ -3,7 +3,7 @@ namespace NIL {} // expected-note {{previous definition}} inline namespace NIL {} // expected-error {{cannot be reopened as inline}} inline namespace IL {} // expected-note {{previous definition}} -namespace IL {} // expected-error {{cannot be reopened as non-inline}} +namespace IL {} // expected-warning{{inline namespace cannot be re-opened as a non-inline namespace}} namespace {} // expected-note {{previous definition}} inline namespace {} // expected-error {{cannot be reopened as inline}}