Nathan-Huckleberry updated this revision to Diff 212012.
Nathan-Huckleberry added a comment.
Herald added a subscriber: arphaman.
- Rework attribute parsing
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D64838/new/
https://reviews.llvm.org/D64838
Files:
clang/include/clang/Basic/Attr.td
clang/lib/Parse/ParseStmt.cpp
clang/lib/Sema/AnalysisBasedWarnings.cpp
clang/test/Index/blocks.c
clang/test/Index/load-exprs.c
clang/test/Sema/fallthrough-attr.c
clang/test/SemaCXX/switch-implicit-fallthrough.cpp
clang/test/SemaCXX/warn-unused-label-error.cpp
Index: clang/test/SemaCXX/warn-unused-label-error.cpp
===================================================================
--- clang/test/SemaCXX/warn-unused-label-error.cpp
+++ clang/test/SemaCXX/warn-unused-label-error.cpp
@@ -18,9 +18,9 @@
}
void h() {
- D: // expected-warning {{unused label 'D'}}
+ D:
#pragma weak unused_local_static
- __attribute__((unused)) // expected-warning {{declaration does not declare anything}}
+ __attribute__((unused)) // expected-error {{'unused' attribute cannot be applied to a statement}}
;
}
}
Index: clang/test/SemaCXX/switch-implicit-fallthrough.cpp
===================================================================
--- clang/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ clang/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -329,3 +329,15 @@
}
return n;
}
+
+int fallthrough_attribute_spelling(int n) {
+ switch (n) {
+ case 0:
+ n++;
+ __attribute__((fallthrough));
+ case 1:
+ n++;
+ break;
+ }
+ return n;
+}
Index: clang/test/Sema/fallthrough-attr.c
===================================================================
--- /dev/null
+++ clang/test/Sema/fallthrough-attr.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -std=gnu89 -verify -Wimplicit-fallthrough %s
+
+int foo(int x) {
+ int a = 0;
+
+ switch (x) {
+ case 0:
+ a++;
+ case 1:
+ // expected-warning@-1{{unannotated fall-through between switch labels}}
+ //expected-note@-2{{insert 'break;' to avoid fall-through}}
+ a--;
+ case 2:
+ // expected-warning@-1{{unannotated fall-through between switch labels}}
+ // expected-note@-2{{insert 'break;' to avoid fall-through}}
+ break;
+ default:
+ a = 1;
+ }
+
+ return 0;
+}
+
+int bar(int x) {
+ int a = 0;
+
+ switch (x) {
+ case 0:
+ a++;
+ __attribute__((fallthrough));
+ case 1:
+ a--;
+ __attribute__((fallthrough));
+ case 2:
+ break;
+ default:
+ a = 1;
+ }
+
+ return 0;
+}
+
+__attribute__((fallthrough)); // expected-warning {{declaration does not declare anything}}
+void baz(int x) {
+ __attribute__((fallthrough)); // expected-error {{fallthrough annotation is outside switch statement}}
+}
Index: clang/test/Index/load-exprs.c
===================================================================
--- clang/test/Index/load-exprs.c
+++ clang/test/Index/load-exprs.c
@@ -52,7 +52,7 @@
// CHECK: load-exprs.c:7:23: DeclRefExpr=x:6:12 Extent=[7:23 - 7:24]
// CHECK: load-exprs.c:10:5: FunctionDecl=test_blocks:10:5 (Definition) Extent=[10:1 - 21:2]
// CHECK: load-exprs.c:10:21: ParmDecl=x:10:21 (Definition) Extent=[10:17 - 10:22]
-// CHECK: load-exprs.c:11:15: VarDecl=y:11:15 (Definition) Extent=[11:3 - 11:20]
+// CHECK: load-exprs.c:11:15: VarDecl=y:11:15 (Definition) Extent=[11:11 - 11:20]
// CHECK: load-exprs.c:11:19: DeclRefExpr=x:10:21 Extent=[11:19 - 11:20]
// CHECK: load-exprs.c:12:3: CallExpr= Extent=[12:3 - 19:7]
// CHECK: load-exprs.c:13:17: VarDecl=z:13:17 (Definition) Extent=[13:6 - 13:22]
Index: clang/test/Index/blocks.c
===================================================================
--- clang/test/Index/blocks.c
+++ clang/test/Index/blocks.c
@@ -14,7 +14,7 @@
// CHECK: blocks.c:7:3: DeclStmt= Extent=[7:3 - 7:26]
// CHECK: blocks.c:7:21: VarDecl=_foo:7:21 (Definition) Extent=[7:3 - 7:25]
// CHECK: blocks.c:7:17: TypeRef=struct foo:4:8 Extent=[7:17 - 7:20]
-// CHECK: blocks.c:8:11: VarDecl=i:8:11 (Definition) Extent=[8:3 - 8:16]
+// CHECK: blocks.c:8:11: VarDecl=i:8:11 (Definition) Extent=[8:11 - 8:16]
// CHECK: blocks.c:8:15: IntegerLiteral= Extent=[8:15 - 8:16]
// CHECK: blocks.c:9:3: CallExpr= Extent=[9:3 - 9:65]
// CHECK: blocks.c:9:3: BlockExpr= Extent=[9:3 - 9:58]
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1215,7 +1215,7 @@
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 @@
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,7 +1276,7 @@
SourceLocation L = Label->getBeginLoc();
if (L.isMacroID())
continue;
- if (S.getLangOpts().CPlusPlus11) {
+ if (S.getLangOpts().CPlusPlus11 || S.getLangOpts().C99) {
const Stmt *Term = B->getTerminatorStmt();
// Skip empty cases.
while (B->empty() && !Term && B->succ_size() == 1) {
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -100,6 +100,7 @@
ParsedAttributesWithRange Attrs(AttrFactory);
MaybeParseCXX11Attributes(Attrs, nullptr, /*MightBeObjCMessageSend*/ true);
+
if (!MaybeParseOpenCLUnrollHintAttribute(Attrs))
return StmtError();
@@ -153,6 +154,8 @@
SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs) {
const char *SemiError = nullptr;
StmtResult Res;
+ bool SeenGNUAttributes = false;
+ 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 +211,13 @@
if ((getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt ||
(StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
ParsedStmtContext()) &&
- isDeclarationStatement()) {
+ (SeenGNUAttributes || isDeclarationStatement())) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Decl = ParseDeclaration(DeclaratorContext::BlockContext,
DeclEnd, Attrs);
+ if(SeenGNUAttributes) {
+ DeclStart = GNUAttributeLoc;
+ }
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
@@ -223,6 +229,13 @@
return ParseExprStatement(StmtCtx);
}
+ case tok::kw___attribute: {
+ SeenGNUAttributes = true;
+ GNUAttributeLoc = Tok.getLocation();
+ MaybeParseGNUAttributes(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
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1170,7 +1170,7 @@
def FallThrough : StmtAttr {
let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">,
- CXX11<"clang", "fallthrough">];
+ CXX11<"clang", "fallthrough">, GCC<"fallthrough">];
// let Subjects = [NullStmt];
let Documentation = [FallthroughDocs];
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits