[clang] ba545c8 - [Sema] Try 2: Attempt to perform call-size-specific `__attribute__((alloc_align(param_idx)))` validation

Roman Lebedev via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 24 03:44:47 PST 2020


Author: Roman Lebedev
Date: 2020-01-24T14:42:45+03:00
New Revision: ba545c814bc19c3b1ec9ce88a7f13575e0e4ce1d

URL: https://github.com/llvm/llvm-project/commit/ba545c814bc19c3b1ec9ce88a7f13575e0e4ce1d
DIFF: https://github.com/llvm/llvm-project/commit/ba545c814bc19c3b1ec9ce88a7f13575e0e4ce1d.diff

LOG: [Sema] Try 2: Attempt to perform call-size-specific `__attribute__((alloc_align(param_idx)))` validation

Summary:
`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


This was initially committed in c2a9061ac5166e48fe85ea2b6dbce9457c964958
but reverted in 00756b182398b92abe16559287467079087aa631 because of
suspicious bot failures.

Reviewers: erichkeane, aaron.ballman, hfinkel, rsmith, jdoerfert

Reviewed By: erichkeane

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D72996

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 1f361569e09d..4485539f3f1c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3653,6 +3653,27 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
     }
   }
 
+  if (FDecl && FDecl->hasAttr<AllocAlignAttr>()) {
+    auto *AA = FDecl->getAttr<AllocAlignAttr>();
+    const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
+    if (!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);
 }

diff  --git a/clang/test/Sema/alloc-align-attr.c b/clang/test/Sema/alloc-align-attr.c
index ae514343aff4..aa0fbd2cee3d 100644
--- a/clang/test/Sema/alloc-align-attr.c
+++ b/clang/test/Sema/alloc-align-attr.c
@@ -17,3 +17,15 @@ void *test_no_fn_proto(int x, int y) __attribute__((alloc_align)); // expected-e
 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}}
+}

diff  --git a/clang/test/SemaCXX/alloc-align-attr.cpp b/clang/test/SemaCXX/alloc-align-attr.cpp
index 74cfb7d7e486..f910cbcf2c90 100644
--- a/clang/test/SemaCXX/alloc-align-attr.cpp
+++ b/clang/test/SemaCXX/alloc-align-attr.cpp
@@ -23,13 +23,19 @@ void* dependent_param_func(T param) __attribute__((alloc_align(1)));// expected-
 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);


        


More information about the cfe-commits mailing list