Nathan-Huckleberry created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixed extraneous matches of non-NullStmt


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64838

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/test/Sema/fallthrough-attr.c
  clang/test/SemaCXX/switch-implicit-fallthrough.cpp

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,48 @@
+// 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/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/ParseTentative.cpp
===================================================================
--- clang/lib/Parse/ParseTentative.cpp
+++ clang/lib/Parse/ParseTentative.cpp
@@ -2121,3 +2121,28 @@
     return TPResult::Ambiguous;
   return TPResult::False;
 }
+
+Parser::TPResult Parser::TryParseNullStmtWithAttributes() {
+  if(Tok.isNot(tok::kw___attribute)) {
+    return TPResult::False;
+  }
+  ParsedAttributesWithRange attrs(AttrFactory);
+  ParseGNUAttributes(attrs, nullptr, nullptr);
+  if(attrs.size() <= 0) {
+    return TPResult::False;
+  }
+  for(auto &attr : attrs) {
+    if(!attr.isStmtAttr()) {
+      return TPResult::False;
+    }
+  }
+  if(Tok.isNot(tok::semi)) {
+    return TPResult::False;
+  }
+  return TPResult::True;
+}
+
+bool Parser::isNullStmtWithAttributes() {
+  RevertingTentativeParsingAction PA(*this);
+  return TryParseNullStmtWithAttributes() == TPResult::True;
+}
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -100,6 +100,11 @@
 
   ParsedAttributesWithRange Attrs(AttrFactory);
   MaybeParseCXX11Attributes(Attrs, nullptr, /*MightBeObjCMessageSend*/ true);
+
+  if(isNullStmtWithAttributes()) {
+    MaybeParseGNUAttributes(Attrs);
+  }
+
   if (!MaybeParseOpenCLUnrollHintAttribute(Attrs))
     return StmtError();
 
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -2326,6 +2326,8 @@
   /// a type-specifier other than a cv-qualifier.
   bool isCXXDeclarationSpecifierAType();
 
+  bool isNullStmtWithAttributes();
+
   /// Determine whether the current token sequence might be
   ///   '<' template-argument-list '>'
   /// rather than a less-than expression.
@@ -2357,6 +2359,7 @@
   TPResult TryParseFunctionDeclarator();
   TPResult TryParseBracketDeclarator();
   TPResult TryConsumeDeclarationSpecifier();
+  TPResult TryParseNullStmtWithAttributes();
 
 public:
   TypeResult ParseTypeName(SourceRange *Range = nullptr,
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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to