summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorNathan Huckleberry <nhuck@google.com>2019-08-20 17:16:49 +0000
committerNathan Huckleberry <nhuck@google.com>2019-08-20 17:16:49 +0000
commit1e0affb6e564b7361b0aadb38805f26deff4ecfc (patch)
tree94ae1566bc130995b7c8b50631cdf4f2ff9e4001 /clang/lib
parent86d560ff1b7101506329331fc392a2d67323d298 (diff)
downloadbcm5719-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.cpp30
-rw-r--r--clang/lib/Parse/ParseStmt.cpp20
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp58
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; ");
}
}
OpenPOWER on IntegriCloud