[PATCH] D72996: [Sema] Attempt to perform call-size-specific `__attribute__((alloc_align(param_idx)))` validation

Roman Lebedev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 19 03:55:33 PST 2020


lebedev.ri created this revision.
lebedev.ri added reviewers: erichkeane, aaron.ballman, hfinkel, rsmith, jdoerfert.
lebedev.ri added a project: LLVM.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
lebedev.ri added a parent revision: D72994: [Sema] Sanity-check alignment requested via `__attribute__((assume_aligned(imm)))`.

`alloc_align` attribute takes parameter number, not the alignment itself,
so given **just** the attribute/function declaration we can't do any
sanity checking for said alignment.

However, at call site, given the actual `Expr` that is passed
into that parameter, we //might// be able to evaluate said `Expr`
as Integer Constant Expression, and perform the sanity checks.
But since there is no requirement for that argument to be an immediate,
we may fail, and that's okay.

However if we did evaluate, we should enforce the same constraints
as with `__builtin_assume_aligned()`/`__attribute__((assume_aligned(imm)))`:
said alignment is a power of two, and is not greater than our magic threshold


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72996

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/alloc-align-attr.c
  clang/test/SemaCXX/alloc-align-attr.cpp


Index: clang/test/SemaCXX/alloc-align-attr.cpp
===================================================================
--- clang/test/SemaCXX/alloc-align-attr.cpp
+++ clang/test/SemaCXX/alloc-align-attr.cpp
@@ -23,13 +23,19 @@
 template <int T>
 void* illegal_align_param(int p) __attribute__((alloc_align(T))); // expected-error {{'alloc_align' attribute requires parameter 1 to be an integer constant}}
 
-void dependent_impl() {
+void dependent_impl(int align) {
   dependent_ret<int> a; // expected-note {{in instantiation of template class 'dependent_ret<int>' requested here}}
   a.Foo(1);
   a.Foo2(1);
-  dependent_ret<int*> b; 
-  a.Foo(1);
-  a.Foo2(1);
+  dependent_ret<int *> b;
+  b.Foo(1);
+  b.Foo2(1);
+  b.Foo(3);           // expected-error {{requested alignment is not a power of 2}}
+  b.Foo2(3);          // expected-error {{requested alignment is not a power of 2}}
+  b.Foo(1073741824);  // expected-warning {{requested alignment must be 536870912 bytes or smaller; maximum alignment assumed}}
+  b.Foo2(1073741824); // expected-warning {{requested alignment must be 536870912 bytes or smaller; maximum alignment assumed}}
+  b.Foo(align);
+  b.Foo2(align);
 
   dependent_param_struct<int> c; 
   c.Foo(1);
Index: clang/test/Sema/alloc-align-attr.c
===================================================================
--- clang/test/Sema/alloc-align-attr.c
+++ clang/test/Sema/alloc-align-attr.c
@@ -17,3 +17,15 @@
 void *test_no_fn_proto(int x, int y) __attribute__((alloc_align())); // expected-error {{'alloc_align' attribute takes one argument}}
 void *test_no_fn_proto(int x, int y) __attribute__((alloc_align(32, 45, 37))); // expected-error {{'alloc_align' attribute takes one argument}}
 
+void *passthrought(int a) {
+  return test_ptr_alloc_align(a);
+}
+void *align16() {
+  return test_ptr_alloc_align(16);
+}
+void *align15() {
+  return test_ptr_alloc_align(15); // expected-error {{requested alignment is not a power of 2}}
+}
+void *align536870912() {
+  return test_ptr_alloc_align(1073741824); // expected-warning {{requested alignment must be 536870912 bytes or smaller; maximum alignment assumed}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -4473,6 +4473,27 @@
     }
   }
 
+  if (FDecl && FDecl->hasAttr<AllocAlignAttr>()) {
+    auto *AA = FDecl->getAttr<AllocAlignAttr>();
+    const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
+    if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+      llvm::APSInt I(64);
+      if (Arg->isIntegerConstantExpr(I, Context)) {
+        if (!I.isPowerOf2()) {
+          Diag(Arg->getExprLoc(), diag::err_alignment_not_power_of_two)
+              << Arg->getSourceRange();
+          return;
+        }
+
+        // Alignment calculations can wrap around if it's greater than 2**29.
+        unsigned MaximumAlignment = 536870912;
+        if (I > MaximumAlignment)
+          Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
+              << Arg->getSourceRange() << MaximumAlignment;
+      }
+    }
+  }
+
   if (FD)
     diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72996.238981.patch
Type: text/x-patch
Size: 3242 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200119/bb8ed181/attachment.bin>


More information about the cfe-commits mailing list