diff options
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 2 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 8 | ||||
-rw-r--r-- | test/Parser/namespaces.cpp | 8 |
3 files changed, 18 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 2795851546..162398dfd2 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -119,6 +119,8 @@ def err_expected_semi_after_namespace_name : Error< "expected ';' after namespace name">; def err_unexpected_namespace_attributes_alias : Error< "attributes can not be specified on namespace alias">; +def err_namespace_nonnamespace_scope : Error< + "namespaces can only be defined in global or namespace scope">; def err_expected_semi_after_attribute_list : Error< "expected ';' after attribute list">; def err_expected_semi_after_static_assert : Error< diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 015ac5b5dd..149efda855 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -87,6 +87,14 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, SourceLocation LBrace = ConsumeBrace(); + if (CurScope->isClassScope() || CurScope->isTemplateParamScope() || + CurScope->isInObjcMethodScope() || CurScope->getBlockParent() || + CurScope->getFnParent()) { + Diag(LBrace, diag::err_namespace_nonnamespace_scope); + SkipUntil(tok::r_brace, false); + return DeclPtrTy(); + } + // Enter a scope for the namespace. ParseScope NamespaceScope(this, Scope::DeclScope); diff --git a/test/Parser/namespaces.cpp b/test/Parser/namespaces.cpp new file mode 100644 index 0000000000..b8c7819a01 --- /dev/null +++ b/test/Parser/namespaces.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR6596 +namespace g { enum { o = 0 }; } + +void foo() { + namespace a { typedef g::o o; } // expected-error{{namespaces can only be defined in global or namespace scope}} +} |