[compiler-rt] [llvm] [flang] [clang] [clang-tools-extra] [clang] Add support for new loop attribute [[clang::code_align()]] (PR #70762)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 16 12:07:58 PST 2023


================
@@ -322,6 +322,61 @@ static Attr *handleUnlikely(Sema &S, Stmt *St, const ParsedAttr &A,
   return ::new (S.Context) UnlikelyAttr(S.Context, A);
 }
 
+CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI,
+                                        Expr *E) {
+  if (!E->isValueDependent()) {
+    llvm::APSInt ArgVal;
+    ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal);
+    if (Res.isInvalid())
+      return nullptr;
+    E = Res.get();
+
+    // This attribute requires an integer argument which is a constant power of
+    // two between 1 and 4096 inclusive.
+    if (ArgVal < CodeAlignAttr::MinimumAlignment ||
+        ArgVal > CodeAlignAttr::MaximumAlignment || !ArgVal.isPowerOf2()) {
+      if (std::optional<int64_t> Value = ArgVal.trySExtValue())
+        Diag(CI.getLoc(), diag::err_attribute_power_of_two_in_range)
+            << CI << CodeAlignAttr::MinimumAlignment
+            << CodeAlignAttr::MaximumAlignment << Value.value();
+      else
+        Diag(CI.getLoc(), diag::err_attribute_power_of_two_in_range)
+            << CI << CodeAlignAttr::MinimumAlignment
+            << CodeAlignAttr::MaximumAlignment << E;
+      return nullptr;
+    }
+  }
+  return new (Context) CodeAlignAttr(Context, CI, E);
+}
+
+static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) {
+
+  Expr *E = A.getArgAsExpr(0);
+  return S.BuildCodeAlignAttr(A, E);
+}
+
+// Emit duplicate error for [[clang::code_align()]] attribute.
+static void
+CheckForDuplicateCodeAlignAttrs(Sema &S,
+                                const SmallVectorImpl<const Attr *> &Attrs) {
+  auto FindFunc = [](const Attr *A) {
+    return isa<const CodeAlignAttr>(A);
+  };
+
+  const auto *FirstItr =
+    std::find_if(Attrs.begin(), Attrs.end(), FindFunc);
+
+  if (FirstItr == Attrs.end()) // no attributes found
+    return;
+
+  const auto *LastFoundItr = FirstItr;
+
+  while (Attrs.end() != (LastFoundItr = std::find_if(LastFoundItr + 1, Attrs.end(), FindFunc)))  {
+      S.Diag((*LastFoundItr)->getLocation(), diag::err_loop_attr_duplication) << *FirstItr;
----------------
AaronBallman wrote:

Yeah, if the attributes resolve to the same values in each case, there's really no harm in accepting the code (we do this for declaration attributes pretty regularly). However, I'd also be fine with "last attribute wins" in the case of multiple attributes with conflicting values.

https://github.com/llvm/llvm-project/pull/70762


More information about the cfe-commits mailing list