diff options
author | Nathan Huckleberry <nhuck@google.com> | 2019-08-20 17:16:49 +0000 |
---|---|---|
committer | Nathan Huckleberry <nhuck@google.com> | 2019-08-20 17:16:49 +0000 |
commit | 1e0affb6e564b7361b0aadb38805f26deff4ecfc (patch) | |
tree | 94ae1566bc130995b7c8b50631cdf4f2ff9e4001 /clang/lib | |
parent | 86d560ff1b7101506329331fc392a2d67323d298 (diff) | |
download | bcm5719-llvm-1e0affb6e564b7361b0aadb38805f26deff4ecfc.tar.gz bcm5719-llvm-1e0affb6e564b7361b0aadb38805f26deff4ecfc.zip |
[Attr] Support _attribute__ ((fallthrough))
Summary: Fixed extraneous matches of non-NullStmt
Reviewers: aaron.ballman, rsmith, efriedma, xbolva00
Reviewed By: aaron.ballman, rsmith, xbolva00
Subscribers: riccibruno, arphaman, ziangwan, ojeda, xbolva00, nickdesaulniers, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64838
llvm-svn: 369414
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 30 | ||||
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 58 |
3 files changed, 62 insertions, 46 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 5fc36e86b1a..71d1c3b8f4a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1741,9 +1741,10 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs, /// [C++11/C11] static_assert-declaration /// others... [FIXME] /// -Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context, - SourceLocation &DeclEnd, - ParsedAttributesWithRange &attrs) { +Parser::DeclGroupPtrTy +Parser::ParseDeclaration(DeclaratorContext Context, SourceLocation &DeclEnd, + ParsedAttributesWithRange &attrs, + SourceLocation *DeclSpecStart) { ParenBraceBracketBalancer BalancerRAIIObj(*this); // Must temporarily exit the objective-c container scope for // parsing c none objective-c decls. @@ -1763,8 +1764,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context, SourceLocation InlineLoc = ConsumeToken(); return ParseNamespace(Context, DeclEnd, InlineLoc); } - return ParseSimpleDeclaration(Context, DeclEnd, attrs, - true); + return ParseSimpleDeclaration(Context, DeclEnd, attrs, true, nullptr, + DeclSpecStart); case tok::kw_namespace: ProhibitAttributes(attrs); return ParseNamespace(Context, DeclEnd); @@ -1777,7 +1778,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context, SingleDecl = ParseStaticAssertDeclaration(DeclEnd); break; default: - return ParseSimpleDeclaration(Context, DeclEnd, attrs, true); + return ParseSimpleDeclaration(Context, DeclEnd, attrs, true, nullptr, + DeclSpecStart); } // This routine returns a DeclGroup, if the thing we parsed only contains a @@ -1802,11 +1804,14 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context, /// If FRI is non-null, we might be parsing a for-range-declaration instead /// of a simple-declaration. If we find that we are, we also parse the /// for-range-initializer, and place it here. -Parser::DeclGroupPtrTy -Parser::ParseSimpleDeclaration(DeclaratorContext Context, - SourceLocation &DeclEnd, - ParsedAttributesWithRange &Attrs, - bool RequireSemi, ForRangeInit *FRI) { +/// +/// DeclSpecStart is used when decl-specifiers are parsed before parsing +/// the Declaration. The SourceLocation for this Decl is set to +/// DeclSpecStart if DeclSpecStart is non-null. +Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration( + DeclaratorContext Context, SourceLocation &DeclEnd, + ParsedAttributesWithRange &Attrs, bool RequireSemi, ForRangeInit *FRI, + SourceLocation *DeclSpecStart) { // Parse the common declaration-specifiers piece. ParsingDeclSpec DS(*this); @@ -1836,6 +1841,9 @@ Parser::ParseSimpleDeclaration(DeclaratorContext Context, return Actions.ConvertDeclToDeclGroup(TheDecl); } + if (DeclSpecStart) + DS.SetRangeStart(*DeclSpecStart); + DS.takeAttributesFrom(Attrs); return ParseDeclGroup(DS, Context, &DeclEnd, FRI); } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 1187ca9c6a6..0532f94cfbc 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -153,6 +153,7 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs) { const char *SemiError = nullptr; StmtResult Res; + SourceLocation GNUAttributeLoc; // Cases in this switch statement should fall through if the parser expects // the token to end in a semicolon (in which case SemiError should be set), @@ -208,10 +209,17 @@ Retry: if ((getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt || (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) != ParsedStmtContext()) && - isDeclarationStatement()) { + (GNUAttributeLoc.isValid() || isDeclarationStatement())) { SourceLocation DeclStart = Tok.getLocation(), DeclEnd; - DeclGroupPtrTy Decl = ParseDeclaration(DeclaratorContext::BlockContext, - DeclEnd, Attrs); + DeclGroupPtrTy Decl; + if (GNUAttributeLoc.isValid()) { + DeclStart = GNUAttributeLoc; + Decl = ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs, + &GNUAttributeLoc); + } else { + Decl = + ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs); + } return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd); } @@ -223,6 +231,12 @@ Retry: return ParseExprStatement(StmtCtx); } + case tok::kw___attribute: { + GNUAttributeLoc = Tok.getLocation(); + ParseGNUAttributes(Attrs); + goto Retry; + } + case tok::kw_case: // C99 6.8.1: labeled-statement return ParseCaseStatement(StmtCtx); case tok::kw_default: // C99 6.8.1: labeled-statement diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index ce01909f185..01648fea8dd 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1215,7 +1215,7 @@ static StringRef getFallthroughAttrSpelling(Preprocessor &PP, tok::r_square, tok::r_square }; - bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17; + bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17 && !PP.getLangOpts().C2x; StringRef MacroName; if (PreferClangAttr) @@ -1224,24 +1224,19 @@ static StringRef getFallthroughAttrSpelling(Preprocessor &PP, MacroName = PP.getLastMacroWithSpelling(Loc, FallthroughTokens); if (MacroName.empty() && !PreferClangAttr) MacroName = PP.getLastMacroWithSpelling(Loc, ClangFallthroughTokens); - if (MacroName.empty()) - MacroName = PreferClangAttr ? "[[clang::fallthrough]]" : "[[fallthrough]]"; + if (MacroName.empty()) { + if (!PreferClangAttr) + MacroName = "[[fallthrough]]"; + else if (PP.getLangOpts().CPlusPlus) + MacroName = "[[clang::fallthrough]]"; + else + MacroName = "__attribute__((fallthrough))"; + } return MacroName; } static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, bool PerFunction) { - // Only perform this analysis when using [[]] attributes. There is no good - // workflow for this warning when not using C++11. There is no good way to - // silence the warning (no attribute is available) unless we are using - // [[]] attributes. One could use pragmas to silence the warning, but as a - // general solution that is gross and not in the spirit of this warning. - // - // NOTE: This an intermediate solution. There are on-going discussions on - // how to properly support this warning outside of C++11 with an annotation. - if (!AC.getASTContext().getLangOpts().DoubleSquareBracketAttributes) - return; - FallthroughMapper FM(S); FM.TraverseStmt(AC.getBody()); @@ -1281,25 +1276,24 @@ static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, SourceLocation L = Label->getBeginLoc(); if (L.isMacroID()) continue; - if (S.getLangOpts().CPlusPlus11) { - const Stmt *Term = B->getTerminatorStmt(); - // Skip empty cases. - while (B->empty() && !Term && B->succ_size() == 1) { - B = *B->succ_begin(); - Term = B->getTerminatorStmt(); - } - if (!(B->empty() && Term && isa<BreakStmt>(Term))) { - Preprocessor &PP = S.getPreprocessor(); - StringRef AnnotationSpelling = getFallthroughAttrSpelling(PP, L); - SmallString<64> TextToInsert(AnnotationSpelling); - TextToInsert += "; "; - S.Diag(L, diag::note_insert_fallthrough_fixit) << - AnnotationSpelling << - FixItHint::CreateInsertion(L, TextToInsert); - } + + const Stmt *Term = B->getTerminatorStmt(); + // Skip empty cases. + while (B->empty() && !Term && B->succ_size() == 1) { + B = *B->succ_begin(); + Term = B->getTerminatorStmt(); + } + if (!(B->empty() && Term && isa<BreakStmt>(Term))) { + Preprocessor &PP = S.getPreprocessor(); + StringRef AnnotationSpelling = getFallthroughAttrSpelling(PP, L); + SmallString<64> TextToInsert(AnnotationSpelling); + TextToInsert += "; "; + S.Diag(L, diag::note_insert_fallthrough_fixit) + << AnnotationSpelling + << FixItHint::CreateInsertion(L, TextToInsert); } - S.Diag(L, diag::note_insert_break_fixit) << - FixItHint::CreateInsertion(L, "break; "); + S.Diag(L, diag::note_insert_break_fixit) + << FixItHint::CreateInsertion(L, "break; "); } } |