summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 99dd96c39da..b3920ff01bd 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -715,20 +715,30 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
// The semantic context is always just the current context.
DeclContext *const DC = CurContext;
- // C++1z [dcl.dcl]/8:
+ // C++17 [dcl.dcl]/8:
// The decl-specifier-seq shall contain only the type-specifier auto
// and cv-qualifiers.
+ // C++2a [dcl.dcl]/8:
+ // If decl-specifier-seq contains any decl-specifier other than static,
+ // thread_local, auto, or cv-qualifiers, the program is ill-formed.
auto &DS = D.getDeclSpec();
{
SmallVector<StringRef, 8> BadSpecifiers;
SmallVector<SourceLocation, 8> BadSpecifierLocs;
+ SmallVector<StringRef, 8> CPlusPlus20Specifiers;
+ SmallVector<SourceLocation, 8> CPlusPlus20SpecifierLocs;
if (auto SCS = DS.getStorageClassSpec()) {
- BadSpecifiers.push_back(DeclSpec::getSpecifierName(SCS));
- BadSpecifierLocs.push_back(DS.getStorageClassSpecLoc());
+ if (SCS == DeclSpec::SCS_static) {
+ CPlusPlus20Specifiers.push_back(DeclSpec::getSpecifierName(SCS));
+ CPlusPlus20SpecifierLocs.push_back(DS.getStorageClassSpecLoc());
+ } else {
+ BadSpecifiers.push_back(DeclSpec::getSpecifierName(SCS));
+ BadSpecifierLocs.push_back(DS.getStorageClassSpecLoc());
+ }
}
if (auto TSCS = DS.getThreadStorageClassSpec()) {
- BadSpecifiers.push_back(DeclSpec::getSpecifierName(TSCS));
- BadSpecifierLocs.push_back(DS.getThreadStorageClassSpecLoc());
+ CPlusPlus20Specifiers.push_back(DeclSpec::getSpecifierName(TSCS));
+ CPlusPlus20SpecifierLocs.push_back(DS.getThreadStorageClassSpecLoc());
}
if (DS.isConstexprSpecified()) {
BadSpecifiers.push_back("constexpr");
@@ -746,6 +756,16 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
// them when building the underlying variable.
for (auto Loc : BadSpecifierLocs)
Err << SourceRange(Loc, Loc);
+ } else if (!CPlusPlus20Specifiers.empty()) {
+ auto &&Warn = Diag(CPlusPlus20SpecifierLocs.front(),
+ getLangOpts().CPlusPlus2a
+ ? diag::warn_cxx17_compat_decomp_decl_spec
+ : diag::ext_decomp_decl_spec);
+ Warn << (int)CPlusPlus20Specifiers.size()
+ << llvm::join(CPlusPlus20Specifiers.begin(),
+ CPlusPlus20Specifiers.end(), " ");
+ for (auto Loc : CPlusPlus20SpecifierLocs)
+ Warn << SourceRange(Loc, Loc);
}
// We can't recover from it being declared as a typedef.
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef)
OpenPOWER on IntegriCloud