diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-10-17 23:31:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-10-17 23:31:46 +0000 |
commit | d654f2d722d4cb6366edcb8f27e99745fcbae486 (patch) | |
tree | 9b78a2b6e55ca9a73f5b90e4ede4104d3ca7a641 | |
parent | 07c90ede8069029b956a2f667282fa0ce1382c4b (diff) |
DR1528: C++11 doesn't allow repeated cv-qualifiers in declarators after all.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166152 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Sema/DeclSpec.h | 3 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 12 | ||||
-rw-r--r-- | test/Parser/cxx0x-decl.cpp | 14 |
4 files changed, 20 insertions, 21 deletions
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 6a4a9ce4e6..0728e87376 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -600,8 +600,7 @@ public: } bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang, - bool IsTypeSpec); + unsigned &DiagID, const LangOptions &Lang); bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 3e4d92abe8..26175a50f5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2741,15 +2741,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // cv-qualifier: case tok::kw_const: isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID, - getLangOpts(), /*IsTypeSpec*/true); + getLangOpts()); break; case tok::kw_volatile: isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, - getLangOpts(), /*IsTypeSpec*/true); + getLangOpts()); break; case tok::kw_restrict: isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, - getLangOpts(), /*IsTypeSpec*/true); + getLangOpts()); break; // C++ typename-specifier: @@ -3948,15 +3948,15 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, case tok::kw_const: isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, - getLangOpts(), /*IsTypeSpec*/false); + getLangOpts()); break; case tok::kw_volatile: isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, - getLangOpts(), /*IsTypeSpec*/false); + getLangOpts()); break; case tok::kw_restrict: isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, - getLangOpts(), /*IsTypeSpec*/false); + getLangOpts()); break; // OpenCL qualifiers: diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 971fc721c1..b3066eb080 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -680,15 +680,13 @@ bool DeclSpec::SetTypeSpecError() { } bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang, - bool IsTypeSpec) { - // Duplicates are permitted in C99, and are permitted in C++11 unless the - // cv-qualifier appears as a type-specifier. However, since this is likely - // not what the user intended, we will always warn. We do not need to set the - // qualifier's location since we already have it. + unsigned &DiagID, const LangOptions &Lang) { + // Duplicates are permitted in C99, but are not permitted in C++. However, + // since this is likely not what the user intended, we will always warn. We + // do not need to set the qualifier's location since we already have it. if (TypeQualifiers & T) { bool IsExtension = true; - if (Lang.C99 || (Lang.CPlusPlus0x && !IsTypeSpec)) + if (Lang.C99) IsExtension = false; return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); } diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp index 13c7fbf0b0..3af73f95c7 100644 --- a/test/Parser/cxx0x-decl.cpp +++ b/test/Parser/cxx0x-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic %s +// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic-errors %s // Make sure we know these are legitimate commas and not typos for ';'. namespace Commas { @@ -23,12 +23,14 @@ class ExtraSemiAfterMemFn { void f() = delete // expected-error {{expected ';' after delete}} void g() = delete; // ok void h() = delete;; // ok - void i() = delete;;; // expected-warning {{extra ';' after member function definition}} + void i() = delete;;; // expected-error {{extra ';' after member function definition}} }; -// This is technically okay, but not likely what the user expects, so we will -// pedantically warn on it -int *const const p = 0; // expected-warning {{duplicate 'const' declaration specifier}} -const const int *q = 0; // expected-warning {{duplicate 'const' declaration specifier}} +int *const const p = 0; // expected-error {{duplicate 'const' declaration specifier}} +const const int *q = 0; // expected-error {{duplicate 'const' declaration specifier}} + +struct MultiCV { + void f() const const; // expected-error {{duplicate 'const' declaration specifier}} +}; static_assert(something, ""); // expected-error {{undeclared identifier}} |