diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -306,21 +306,30 @@ if (!DiagnoseMutualExclusions(S, Attrs)) return; - // There are 6 categories of loop hints attributes: vectorize, interleave, - // unroll, unroll_and_jam, pipeline and distribute. Except for distribute they - // come in two variants: a state form and a numeric form. The state form - // selectively defaults/enables/disables the transformation for the loop - // (for unroll, default indicates full unrolling rather than enabling the - // transformation). The numeric form form provides an integer hint (for - // example, unroll count) to the transformer. The following array accumulates - // the hints encountered while iterating through the attributes to check for - // compatibility. + enum CategoryType { + Vectorize, + Interleave, + Unroll, + UnrollAndJam, + Distribute, + Pipeline, + VectorizePredicate, + NumberOfCategories + }; + // There are 7 categories of loop hints attributes: vectorize, interleave, + // unroll, unroll_and_jam, pipeline, distribute, and vectorize predicate. + // Except for distribute and vectorize predicate, they come in two variants: a + // state form and a numeric form. The state form selectively + // defaults/enables/disables the transformation for the loop (for unroll, + // default indicates full unrolling rather than enabling the transformation). + // The numeric form form provides an integer hint (for example, unroll count) + // to the transformer. The following array accumulates the hints encountered + // while iterating through the attributes to check for compatibility. struct { const LoopHintAttr *StateAttr; const LoopHintAttr *NumericAttr; - } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, - {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, - {nullptr, nullptr}}; + } HintAttrs[CategoryType::NumberOfCategories]; + memset(HintAttrs, 0, sizeof(HintAttrs)); for (const auto *I : Attrs) { const LoopHintAttr *LH = dyn_cast(I); @@ -329,16 +338,8 @@ if (!LH) continue; + CategoryType Category = CategoryType::NumberOfCategories; LoopHintAttr::OptionType Option = LH->getOption(); - enum { - Vectorize, - Interleave, - Unroll, - UnrollAndJam, - Distribute, - Pipeline, - VectorizePredicate - } Category; switch (Option) { case LoopHintAttr::Vectorize: case LoopHintAttr::VectorizeWidth: @@ -369,7 +370,7 @@ break; }; - assert(Category < sizeof(HintAttrs) / sizeof(HintAttrs[0])); + assert(Category != NumberOfCategories && "Unhandled loop hint option"); auto &CategoryState = HintAttrs[Category]; const LoopHintAttr *PrevAttr; if (Option == LoopHintAttr::Vectorize ||