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

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 8 09:05:32 PST 2016


This causes clang to warn on

  default: assert (false); HB_FALLTHROUGH;

The fallthrough needs to be there for release builds, but now it must not
be there for debug builds. I suppose this means projects now need an
UNREACHED_CASE macro that expands to assert(false) in debug and to
fallthrough in release (with clang; and to something else with other
compilers)?

On Mon, Mar 7, 2016 at 7:32 PM, Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> 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>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160308/91ceb3db/attachment-0001.html>


More information about the cfe-commits mailing list