r262881 - P0188R1: add support for standard [[fallthrough]] attribute. This is almost

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 7 16:32:56 PST 2016


Author: rsmith
Date: Mon Mar  7 18:32:55 2016
New Revision: 262881

URL: http://llvm.org/viewvc/llvm-project?rev=262881&view=rev
Log:
P0188R1: add support for standard [[fallthrough]] attribute. This is almost
exactly the same as clang's existing [[clang::fallthrough]] attribute, which
has been updated to have the same semantics. The one significant difference
is that [[fallthrough]] is ill-formed if it's not used immediately before a
switch label (even when -Wimplicit-fallthrough is disabled). To support that,
we now build a CFG of any function that uses a '[[fallthrough]];' statement
to check.

In passing, fix some bugs with our support for statement attributes -- in
particular, diagnose their use on declarations, rather than asserting.

Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/AttrDocs.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
    cfe/trunk/lib/Sema/AttributeList.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaStmtAttr.cpp
    cfe/trunk/test/Analysis/cxx11-crashes.cpp
    cfe/trunk/test/PCH/Inputs/cxx11-statement-attributes.h
    cfe/trunk/test/PCH/cxx11-statement-attributes.cpp
    cfe/trunk/test/Parser/cxx0x-attributes.cpp
    cfe/trunk/test/SemaCXX/for-range-examples.cpp
    cfe/trunk/test/SemaCXX/generalized-deprecated.cpp
    cfe/trunk/test/SemaCXX/nodiscard.cpp
    cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-macro.cpp
    cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
    cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp
    cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Mon Mar  7 18:32:55 2016
@@ -118,6 +118,19 @@ public:
   bool duplicatesAllowed() const { return DuplicatesAllowed; }
 };
 
+class StmtAttr : public Attr {
+protected:
+  StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
+                  bool IsLateParsed, bool DuplicatesAllowed)
+      : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
+
+public:
+  static bool classof(const Attr *A) {
+    return A->getKind() >= attr::FirstStmtAttr &&
+           A->getKind() <= attr::LastStmtAttr;
+  }
+};
+
 class InheritableAttr : public Attr {
 protected:
   InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Mon Mar  7 18:32:55 2016
@@ -311,6 +311,9 @@ class TypeAttr : Attr {
   let ASTNode = 0;
 }
 
+/// A stmt attribute is not processed on a declaration or a type.
+class StmtAttr : Attr;
+
 /// An inheritable attribute is inherited by later redeclarations.
 class InheritableAttr : Attr;
 
@@ -738,8 +741,9 @@ def ExtVectorType : Attr {
   let Documentation = [Undocumented];
 }
 
-def FallThrough : Attr {
-  let Spellings = [CXX11<"clang", "fallthrough">];
+def FallThrough : StmtAttr {
+  let Spellings = [CXX11<"", "fallthrough", 201503>,
+                   CXX11<"clang", "fallthrough">];
 //  let Subjects = [NullStmt];
   let Documentation = [FallthroughDocs];
 }

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon Mar  7 18:32:55 2016
@@ -756,9 +756,10 @@ potentially-evaluated discarded-value ex
 
 def FallthroughDocs : Documentation {
   let Category = DocCatStmt;
+  let Heading = "fallthrough, clang::fallthrough";
   let Content = [{
-The ``clang::fallthrough`` attribute is used along with the
-``-Wimplicit-fallthrough`` argument to annotate intentional fall-through
+The ``fallthrough`` (or ``clang::fallthrough``) attribute is used
+to annotate intentional fall-through
 between switch labels.  It can only be applied to a null statement placed at a
 point of execution between any statement and the next switch label.  It is
 common to mark these places with a specific comment, but this attribute is
@@ -769,6 +770,10 @@ control-flow statements like ``break;``,
 where ``break;`` can, but only if there are no statements on the execution path
 between it and the next switch label.
 
+By default, Clang does not warn on unannotated fallthrough from one ``switch``
+case to another. Diagnostics on fallthrough without a corresponding annotation
+can be enabled with the ``-Wimplicit-fallthrough`` argument.
+
 Here is an example:
 
 .. code-block:: c++

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar  7 18:32:55 2016
@@ -2358,8 +2358,10 @@ def warn_cxx11_gnu_attribute_on_type : W
 def warn_unhandled_ms_attribute_ignored : Warning<
   "__declspec attribute %0 is not supported">, 
   InGroup<IgnoredAttributes>;
-def err_attribute_invalid_on_stmt : Error<
+def err_decl_attribute_invalid_on_stmt : Error<
   "%0 attribute cannot be applied to a statement">;
+def err_stmt_attribute_invalid_on_decl : Error<
+  "%0 attribute cannot be applied to a declaration">;
 def warn_declspec_attribute_ignored : Warning<
   "attribute %0 is ignored, place it after "
   "\"%select{class|struct|interface|union|enum}1\" to apply attribute to "
@@ -6592,8 +6594,11 @@ def warn_unused_result : Warning<
 def warn_unused_volatile : Warning<
   "expression result unused; assign into a variable to force a volatile load">,
   InGroup<DiagGroup<"unused-volatile-lvalue">>;
-def ext_nodiscard_attr_is_a_cxx1z_extension : ExtWarn<
-  "use of the 'nodiscard' attribute is a C++1z extension">, InGroup<CXX1z>;
+
+def ext_cxx14_attr : Extension<
+  "use of the %0 attribute is a C++14 extension">, InGroup<CXX14>;
+def ext_cxx1z_attr : Extension<
+  "use of the %0 attribute is a C++1z extension">, InGroup<CXX1z>;
 
 def warn_unused_comparison : Warning<
   "%select{%select{|in}1equality|relational}0 comparison result unused">,
@@ -7306,13 +7311,12 @@ def note_insert_fallthrough_fixit : Note
 def note_insert_break_fixit : Note<
   "insert 'break;' to avoid fall-through">;
 def err_fallthrough_attr_wrong_target : Error<
-  "clang::fallthrough attribute is only allowed on empty statements">;
+  "%0 attribute is only allowed on empty statements">;
 def note_fallthrough_insert_semi_fixit : Note<"did you forget ';'?">;
 def err_fallthrough_attr_outside_switch : Error<
   "fallthrough annotation is outside switch statement">;
-def warn_fallthrough_attr_invalid_placement : Warning<
-  "fallthrough annotation does not directly precede switch label">,
-  InGroup<ImplicitFallthrough>;
+def err_fallthrough_attr_invalid_placement : Error<
+  "fallthrough annotation does not directly precede switch label">;
 def warn_fallthrough_attr_unreachable : Warning<
   "fallthrough annotation in unreachable code">,
   InGroup<ImplicitFallthrough>;
@@ -7678,9 +7682,6 @@ def err_asm_naked_this_ref : Error<
 def err_asm_naked_parm_ref : Error<
   "parameter references not allowed in naked functions">;
 
-def ext_deprecated_attr_is_a_cxx14_extension : ExtWarn<
-  "use of the 'deprecated' attribute is a C++14 extension">, InGroup<CXX14>;
-
 // OpenCL warnings and errors.
 def err_invalid_astype_of_different_size : Error<
   "invalid reinterpretation: sizes of %0 and %1 must match">;

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Mon Mar  7 18:32:55 2016
@@ -491,6 +491,7 @@ public:
 
   bool isTargetSpecificAttr() const;
   bool isTypeAttr() const;
+  bool isStmtAttr() const;
 
   bool hasCustomParsing() const;
   unsigned getMinArgs() const;

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Mon Mar  7 18:32:55 2016
@@ -107,6 +107,9 @@ public:
   /// \brief True if current scope is for OpenMP declare reduction combiner.
   bool HasOMPDeclareReductionCombiner;
 
+  /// \brief Whether there is a fallthrough statement in this function.
+  bool HasFallthroughStmt : 1;
+
   /// A flag that is set when parsing a method that must call super's
   /// implementation, such as \c -dealloc, \c -finalize, or any method marked
   /// with \c __attribute__((objc_requires_super)).
@@ -348,6 +351,10 @@ public:
     HasOMPDeclareReductionCombiner = true;
   }
 
+  void setHasFallthroughStmt() {
+    HasFallthroughStmt = true;
+  }
+
   void setHasCXXTry(SourceLocation TryLoc) {
     setHasBranchProtectedScope();
     FirstCXXTryLoc = TryLoc;
@@ -371,6 +378,7 @@ public:
       HasIndirectGoto(false),
       HasDroppedStmt(false),
       HasOMPDeclareReductionCombiner(false),
+      HasFallthroughStmt(false),
       ObjCShouldCallSuper(false),
       ObjCIsDesignatedInit(false),
       ObjCWarnForNoDesignatedInitChain(false),

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Mon Mar  7 18:32:55 2016
@@ -1071,6 +1071,34 @@ namespace {
   };
 } // anonymous namespace
 
+static StringRef getFallthroughAttrSpelling(Preprocessor &PP,
+                                            SourceLocation Loc) {
+  TokenValue FallthroughTokens[] = {
+    tok::l_square, tok::l_square,
+    PP.getIdentifierInfo("fallthrough"),
+    tok::r_square, tok::r_square
+  };
+
+  TokenValue ClangFallthroughTokens[] = {
+    tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
+    tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
+    tok::r_square, tok::r_square
+  };
+
+  bool PreferClangAttr = !PP.getLangOpts().CPlusPlus1z;
+
+  StringRef MacroName;
+  if (PreferClangAttr)
+    MacroName = PP.getLastMacroWithSpelling(Loc, ClangFallthroughTokens);
+  if (MacroName.empty())
+    MacroName = PP.getLastMacroWithSpelling(Loc, FallthroughTokens);
+  if (MacroName.empty() && !PreferClangAttr)
+    MacroName = PP.getLastMacroWithSpelling(Loc, ClangFallthroughTokens);
+  if (MacroName.empty())
+    MacroName = PreferClangAttr ? "[[clang::fallthrough]]" : "[[fallthrough]]";
+  return MacroName;
+}
+
 static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
                                             bool PerFunction) {
   // Only perform this analysis when using C++11.  There is no good workflow
@@ -1129,15 +1157,7 @@ static void DiagnoseSwitchLabelsFallthro
         }
         if (!(B->empty() && Term && isa<BreakStmt>(Term))) {
           Preprocessor &PP = S.getPreprocessor();
-          TokenValue Tokens[] = {
-            tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
-            tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
-            tok::r_square, tok::r_square
-          };
-          StringRef AnnotationSpelling = "[[clang::fallthrough]]";
-          StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens);
-          if (!MacroName.empty())
-            AnnotationSpelling = MacroName;
+          StringRef AnnotationSpelling = getFallthroughAttrSpelling(PP, L);
           SmallString<64> TextToInsert(AnnotationSpelling);
           TextToInsert += "; ";
           S.Diag(L, diag::note_insert_fallthrough_fixit) <<
@@ -1151,7 +1171,7 @@ static void DiagnoseSwitchLabelsFallthro
   }
 
   for (const auto *F : FM.getFallthroughStmts())
-    S.Diag(F->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
+    S.Diag(F->getLocStart(), diag::err_fallthrough_attr_invalid_placement);
 }
 
 static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM,
@@ -2038,7 +2058,8 @@ AnalysisBasedWarnings::IssueWarnings(sem
       !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart());
   bool FallThroughDiagPerFunction = !Diags.isIgnored(
       diag::warn_unannotated_fallthrough_per_function, D->getLocStart());
-  if (FallThroughDiagFull || FallThroughDiagPerFunction) {
+  if (FallThroughDiagFull || FallThroughDiagPerFunction ||
+      fscope->HasFallthroughStmt) {
     DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
   }
 

Modified: cfe/trunk/lib/Sema/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AttributeList.cpp (original)
+++ cfe/trunk/lib/Sema/AttributeList.cpp Mon Mar  7 18:32:55 2016
@@ -159,6 +159,7 @@ struct ParsedAttrInfo {
   unsigned HasCustomParsing : 1;
   unsigned IsTargetSpecific : 1;
   unsigned IsType : 1;
+  unsigned IsStmt : 1;
   unsigned IsKnownToGCC : 1;
 
   bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
@@ -204,6 +205,10 @@ bool AttributeList::isTypeAttr() const {
   return getInfo(*this).IsType;
 }
 
+bool AttributeList::isStmtAttr() const {
+  return getInfo(*this).IsStmt;
+}
+
 bool AttributeList::existsInTarget(const TargetInfo &Target) const {
   return getInfo(*this).ExistsInTarget(Target);
 }

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Mar  7 18:32:55 2016
@@ -2467,7 +2467,7 @@ static void handleWarnUnusedResult(Sema
   // about using it as an extension.
   if (!S.getLangOpts().CPlusPlus1z && Attr.isCXX11Attribute() &&
       !Attr.getScopeName())
-    S.Diag(Attr.getLoc(), diag::ext_nodiscard_attr_is_a_cxx1z_extension);
+    S.Diag(Attr.getLoc(), diag::ext_cxx1z_attr) << Attr.getName();
 
   D->addAttr(::new (S.Context) 
              WarnUnusedResultAttr(Attr.getRange(), S.Context,
@@ -5072,7 +5072,7 @@ static void handleDeprecatedAttr(Sema &S
   if (!S.getLangOpts().CPlusPlus14)
     if (Attr.isCXX11Attribute() &&
         !(Attr.hasScope() && Attr.getScopeName()->isStr("gnu")))
-      S.Diag(Attr.getLoc(), diag::ext_deprecated_attr_is_a_cxx14_extension);
+      S.Diag(Attr.getLoc(), diag::ext_cxx14_attr) << Attr.getName();
 
   handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
 }
@@ -5234,8 +5234,13 @@ static void ProcessDeclAttribute(Sema &S
 
   switch (Attr.getKind()) {
   default:
-    // Type attributes are handled elsewhere; silently move on.
-    assert(Attr.isTypeAttr() && "Non-type attribute not handled");
+    if (!Attr.isStmtAttr()) {
+      // Type attributes are handled elsewhere; silently move on.
+      assert(Attr.isTypeAttr() && "Non-type attribute not handled");
+      break;
+    }
+    S.Diag(Attr.getLoc(), diag::err_stmt_attribute_invalid_on_decl)
+        << Attr.getName() << D->getLocation();
     break;
   case AttributeList::AT_Interrupt:
     handleInterruptAttr(S, D, Attr);

Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Mon Mar  7 18:32:55 2016
@@ -25,9 +25,11 @@ using namespace sema;
 
 static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const AttributeList &A,
                                    SourceRange Range) {
+  FallThroughAttr Attr(A.getRange(), S.Context,
+                       A.getAttributeSpellingListIndex());
   if (!isa<NullStmt>(St)) {
     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_wrong_target)
-        << St->getLocStart();
+        << Attr.getSpelling() << St->getLocStart();
     if (isa<SwitchCase>(St)) {
       SourceLocation L = S.getLocForEndOfToken(Range.getEnd());
       S.Diag(L, diag::note_fallthrough_insert_semi_fixit)
@@ -35,12 +37,20 @@ static Attr *handleFallThroughAttr(Sema
     }
     return nullptr;
   }
-  if (S.getCurFunction()->SwitchStack.empty()) {
+  auto *FnScope = S.getCurFunction();
+  if (FnScope->SwitchStack.empty()) {
     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_outside_switch);
     return nullptr;
   }
-  return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context,
-                                           A.getAttributeSpellingListIndex());
+
+  // If this is spelled as the standard C++1z attribute, but not in C++1z, warn
+  // about using it as an extension.
+  if (!S.getLangOpts().CPlusPlus1z && A.isCXX11Attribute() &&
+      !A.getScopeName())
+    S.Diag(A.getLoc(), diag::ext_cxx1z_attr) << A.getName();
+
+  FnScope->setHasFallthroughStmt();
+  return ::new (S.Context) auto(Attr);
 }
 
 static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
@@ -266,7 +276,7 @@ static Attr *ProcessStmtAttribute(Sema &
   default:
     // if we're here, then we parsed a known attribute, but didn't recognize
     // it as a statement attribute => it is declaration attribute
-    S.Diag(A.getRange().getBegin(), diag::err_attribute_invalid_on_stmt)
+    S.Diag(A.getRange().getBegin(), diag::err_decl_attribute_invalid_on_stmt)
         << A.getName() << St->getLocStart();
     return nullptr;
   }

Modified: cfe/trunk/test/Analysis/cxx11-crashes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx11-crashes.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/cxx11-crashes.cpp (original)
+++ cfe/trunk/test/Analysis/cxx11-crashes.cpp Mon Mar  7 18:32:55 2016
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core -std=c++11 -verify %s
-// expected-no-diagnostics
 
 // radar://11485149, PR12871
 class PlotPoint {
@@ -91,6 +90,6 @@ void test() {
 void fallthrough() {
   switch (1) {
     case 1:
-      [[clang::fallthrough]];
+      [[clang::fallthrough]]; // expected-error {{does not directly precede}}
   }
 }

Modified: cfe/trunk/test/PCH/Inputs/cxx11-statement-attributes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/cxx11-statement-attributes.h?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/PCH/Inputs/cxx11-statement-attributes.h (original)
+++ cfe/trunk/test/PCH/Inputs/cxx11-statement-attributes.h Mon Mar  7 18:32:55 2016
@@ -7,7 +7,8 @@ int f(int n) {
       [[clang::fallthrough]];  // This shouldn't generate a warning.
     case 1:
       n += 20;
-      [[clang::fallthrough]];  // This should generate a warning: "fallthrough annotation does not directly precede switch label".
+    case 2:  // This should generate a warning: "unannotated fallthrough"
+      n += 35;
       break;
   }
   return n;

Modified: cfe/trunk/test/PCH/cxx11-statement-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx11-statement-attributes.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx11-statement-attributes.cpp (original)
+++ cfe/trunk/test/PCH/cxx11-statement-attributes.cpp Mon Mar  7 18:32:55 2016
@@ -1,10 +1,15 @@
 // Sanity check.
 // RUN: %clang_cc1 -include %S/Inputs/cxx11-statement-attributes.h -std=c++11 -Wimplicit-fallthrough -fsyntax-only %s -o - -verify
+// RUN: %clang_cc1 -include %S/Inputs/cxx11-statement-attributes.h -std=c++1z -Wimplicit-fallthrough -fsyntax-only %s -o - -verify
 // Run the same tests, this time with the attributes loaded from the PCH file.
 // RUN: %clang_cc1 -x c++-header -emit-pch -std=c++11 -o %t %S/Inputs/cxx11-statement-attributes.h
 // RUN: %clang_cc1 -include-pch %t -std=c++11 -Wimplicit-fallthrough -fsyntax-only %s -o - -verify
+// RUN: %clang_cc1 -x c++-header -emit-pch -std=c++1z -o %t %S/Inputs/cxx11-statement-attributes.h
+// RUN: %clang_cc1 -include-pch %t -std=c++1z -Wimplicit-fallthrough -fsyntax-only %s -o - -verify
 
-// expected-warning at Inputs/cxx11-statement-attributes.h:10 {{fallthrough annotation does not directly precede switch label}}
+// expected-warning at Inputs/cxx11-statement-attributes.h:10 {{unannotated fall-through}}
+// expected-note-re at Inputs/cxx11-statement-attributes.h:10 {{insert '[[{{(clang::)?}}fallthrough]];'}}
+// expected-note at Inputs/cxx11-statement-attributes.h:10 {{insert 'break;'}}
 
 void g(int n) {
   f<1>(n);  // expected-note {{in instantiation of function template specialization 'f<1>' requested here}}

Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Mon Mar  7 18:32:55 2016
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat -Wc++14-extensions -Wc++1z-extensions %s
 
 // Need std::initializer_list
 namespace std {
@@ -347,6 +347,18 @@ deprecated
 ]] void bad();
 }
 
+int fallthru(int n) {
+  switch (n) {
+  case 0:
+    n += 5;
+    [[fallthrough]]; // expected-warning {{use of the 'fallthrough' attribute is a C++1z extension}}
+  case 1:
+    n *= 2;
+    break;
+  }
+  return n;
+}
+
 #define attr_name bitand
 #define attr_name_2(x) x
 #define attr_name_3(x, y) x##y

Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)
+++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Mon Mar  7 18:32:55 2016
@@ -226,7 +226,7 @@ namespace test7 {
     // we check the alignment attribute before we perform the auto
     // deduction.
     for (d alignas(1) : arr) {} // expected-error {{requires type for loop variable}}
-    for (e [[deprecated]] : arr) { e = 0; } // expected-warning{{use of the 'deprecated' attribute is a C++14 extension}} expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
+    for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
   }
 }
 

Modified: cfe/trunk/test/SemaCXX/generalized-deprecated.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/generalized-deprecated.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/generalized-deprecated.cpp (original)
+++ cfe/trunk/test/SemaCXX/generalized-deprecated.cpp Mon Mar  7 18:32:55 2016
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions -Wno-deprecated %s
+// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions -Wno-deprecated -Wc++14-extensions %s
 
 // NOTE: use -Wno-deprecated to avoid cluttering the output with deprecated
 // warnings

Modified: cfe/trunk/test/SemaCXX/nodiscard.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nodiscard.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nodiscard.cpp (original)
+++ cfe/trunk/test/SemaCXX/nodiscard.cpp Mon Mar  7 18:32:55 2016
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify -Wc++1z-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT -Wc++1z-extensions %s
 
 #if !defined(EXT)
 static_assert(__has_cpp_attribute(nodiscard) == 201603);

Modified: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-macro.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-macro.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-macro.cpp (original)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-macro.cpp Mon Mar  7 18:32:55 2016
@@ -1,4 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -DCLANG_PREFIX -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] -DUNCHOSEN=[[fallthrough]] %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[fallthrough]] %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -Wimplicit-fallthrough -DCLANG_PREFIX -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[clang::fallthrough]] %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -Wimplicit-fallthrough -DCOMMAND_LINE_FALLTHROUGH=[[fallthrough]] -DUNCHOSEN=[[clang::fallthrough]] %s
 
 int fallthrough_compatibility_macro_from_command_line(int n) {
   switch (n) {
@@ -10,15 +14,12 @@ int fallthrough_compatibility_macro_from
   return n;
 }
 
-#ifdef __clang__
-#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
+#ifdef CLANG_PREFIX
 #define COMPATIBILITY_FALLTHROUGH   [ [ /* test */  clang /* test */ \
     ::  fallthrough  ]  ]    // testing whitespace and comments in macro definition
-#endif
-#endif
-
-#ifndef COMPATIBILITY_FALLTHROUGH
-#define COMPATIBILITY_FALLTHROUGH do { } while (0)
+#else
+#define COMPATIBILITY_FALLTHROUGH   [ [ /* test */  /* test */ \
+    fallthrough  ]  ]    // testing whitespace and comments in macro definition
 #endif
 
 int fallthrough_compatibility_macro_from_source(int n) {
@@ -32,7 +33,11 @@ int fallthrough_compatibility_macro_from
 }
 
 // Deeper macro substitution
+#ifdef CLANG_PREFIX
 #define M1 [[clang::fallthrough]]
+#else
+#define M1 [[fallthrough]]
+#endif
 #ifdef __clang__
 #define M2 M1
 #else
@@ -59,12 +64,17 @@ int fallthrough_compatibility_macro_in_m
 #undef M2
 #undef COMPATIBILITY_FALLTHROUGH
 #undef COMMAND_LINE_FALLTHROUGH
+#undef UNCHOSEN
 
 int fallthrough_compatibility_macro_undefined(int n) {
   switch (n) {
     case 0:
       n = n * 20;
+#if __cplusplus <= 201402L
     case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+#else
+    case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+#endif
       ;
   }
 #define TOO_LATE [[clang::fallthrough]]
@@ -83,7 +93,11 @@ int fallthrough_compatibility_macro_hist
     case 0:
       n = n * 20;
 #undef MACRO_WITH_HISTORY
+#if __cplusplus <= 201402L
     case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+#else
+    case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+#endif
       ;
 #define MACRO_WITH_HISTORY [[clang::fallthrough]]
   }

Modified: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp (original)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp Mon Mar  7 18:32:55 2016
@@ -41,9 +41,8 @@ int fallthrough2(int n) {
 void unscoped(int n) {
   switch (n % 2) {
     case 0:
-      // FIXME: This should be typo-corrected, probably.
-      [[fallthrough]]; // expected-warning{{unknown attribute 'fallthrough' ignored}}
-    case 2: // expected-warning{{unannotated fall-through}} expected-note{{clang::fallthrough}} expected-note{{break;}}
+      [[fallthrough]];
+    case 2:
       [[clang::fallthrough]];
     case 1:
       break;

Modified: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp (original)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp Mon Mar  7 18:32:55 2016
@@ -179,18 +179,15 @@ void fallthrough_cfgblock_with_null_succ
 
 int fallthrough_position(int n) {
   switch (n) {
-      [[clang::fallthrough]];  // expected-warning{{fallthrough annotation does not directly precede switch label}}
       n += 300;
       [[clang::fallthrough]];  // expected-warning{{fallthrough annotation in unreachable code}}
     case 221:
-      [[clang::fallthrough]];  // expected-warning{{fallthrough annotation does not directly precede switch label}}
       return 1;
       [[clang::fallthrough]];  // expected-warning{{fallthrough annotation in unreachable code}}
     case 222:
-      [[clang::fallthrough]];  // expected-warning{{fallthrough annotation does not directly precede switch label}}
       n += 400;
     case 223:          // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
-      [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
+      ;
   }
 
   long p = static_cast<long>(n) * n;
@@ -282,6 +279,23 @@ namespace PR18983 {
   }
 }
 
+int fallthrough_placement_error(int n) {
+  switch (n) {
+      [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
+      n += 300;
+    case 221:
+      [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}}
+      return 1;
+    case 222:
+      [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}}
+      n += 400;
+      [[clang::fallthrough]];
+    case 223:
+      [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}}
+  }
+  return n;
+}
+
 int fallthrough_targets(int n) {
   [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
 

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Mar  7 18:32:55 2016
@@ -1761,6 +1761,7 @@ namespace {
 
 static const AttrClassDescriptor AttrClassDescriptors[] = {
   { "ATTR", "Attr" },
+  { "STMT_ATTR", "StmtAttr" },
   { "INHERITABLE_ATTR", "InheritableAttr" },
   { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
   { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
@@ -2806,6 +2807,7 @@ void EmitClangAttrParsedAttrImpl(RecordK
     SS << ", " << I->second->getValueAsBit("HasCustomParsing");
     SS << ", " << I->second->isSubClassOf("TargetSpecificAttr");
     SS << ", " << I->second->isSubClassOf("TypeAttr");
+    SS << ", " << I->second->isSubClassOf("StmtAttr");
     SS << ", " << IsKnownToGCC(*I->second);
     SS << ", " << GenerateAppertainsTo(*I->second, OS);
     SS << ", " << GenerateLangOptRequirements(*I->second, OS);

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=262881&r1=262880&r2=262881&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Mon Mar  7 18:32:55 2016
@@ -629,7 +629,7 @@ as the draft C++1z standard evolves.</p>
     <tr>
       <td><tt>[[fallthrough]]</tt> attribute</td>
       <td><a href="http://wg21.link/p0188r1">P0188R1</a></td>
-      <td class="none" align="center">No</td>
+      <td class="full" align="center">SVN</td>
     </tr>
     <tr>
       <td><tt>[[nodiscard]]</tt> attribute</td>




More information about the cfe-commits mailing list