diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/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);
 }
diff --git a/clang/test/Sema/alloc-align-attr.c b/clang/test/Sema/alloc-align-attr.c
--- 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-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
--- a/clang/test/SemaCXX/alloc-align-attr.cpp
+++ b/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);