[PATCH] D73019: [Sema] Don't disallow placing `__attribute__((alloc_align(param_idx)))` on `std::align_val_t`-typed parameters

2020-01-23 Thread Roman Lebedev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb749af6a1ff4: [Sema] Don't disallow placing 
`__attribute__((alloc_align(param_idx)))` on `stdā€¦ (authored by lebedev.ri).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73019/new/

https://reviews.llvm.org/D73019

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) 
__attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+struct alignas(128) S {
+  S() {}
+};
+
+void *alloc_overaligned_struct() {
+  return new S;
+}
+
+void *alloc_overaligned_struct_with_extra_variable_alignment(int align) {
+  return new (std::align_val_t(align)) S;
+}
+void *alloc_overaligned_struct_with_extra_256_alignment(int align) {
+  return new (std::align_val_t(256)) S;
+}
+void *alloc_overaligned_struct_with_extra_255_alignment(int align) {
+  return new (std::align_val_t(255)) S;
+}
+
+std::align_val_t align_variable(int align) { return std::align_val_t(align); }
+std::align_val_t align_align16() { return std::align_val_t(16); }
+std::align_val_t align_align15() { return std::align_val_t(15); }
+
+// expected-no-diagnostics
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1667,7 +1667,8 @@
 return;
 
   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
-  if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) {
+  if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+  !Ty->isAlignValT()) {
 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
 << &TmpAttr
 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) __attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+struct alignas(128) S {
+  S() {}
+};
+
+void *alloc_overaligned_struct() {
+  return new S;
+}
+
+void *alloc_overaligned_struct_with_extra_variable_alignment(int align) {
+  return new (std::align_val_t(align)) S;
+}
+void *alloc_overaligned_struct_with_extra_256_alignment(int align) {
+  return new (std::align_val_t(256)) S;
+}
+void *alloc_overaligned_struct_with_extra_255_alignment(int al

[PATCH] D73019: [Sema] Don't disallow placing `__attribute__((alloc_align(param_idx)))` on `std::align_val_t`-typed parameters

2020-01-23 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri updated this revision to Diff 239960.
lebedev.ri added a comment.

Rebased, NFC.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73019/new/

https://reviews.llvm.org/D73019

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) 
__attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+struct alignas(128) S {
+  S() {}
+};
+
+void *alloc_overaligned_struct() {
+  return new S;
+}
+
+void *alloc_overaligned_struct_with_extra_variable_alignment(int align) {
+  return new (std::align_val_t(align)) S;
+}
+void *alloc_overaligned_struct_with_extra_256_alignment(int align) {
+  return new (std::align_val_t(256)) S;
+}
+void *alloc_overaligned_struct_with_extra_255_alignment(int align) {
+  return new (std::align_val_t(255)) S;
+}
+
+std::align_val_t align_variable(int align) { return std::align_val_t(align); }
+std::align_val_t align_align16() { return std::align_val_t(16); }
+std::align_val_t align_align15() { return std::align_val_t(15); }
+
+// expected-no-diagnostics
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1667,7 +1667,8 @@
 return;
 
   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
-  if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) {
+  if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+  !Ty->isAlignValT()) {
 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
 << &TmpAttr
 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) __attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+struct alignas(128) S {
+  S() {}
+};
+
+void *alloc_overaligned_struct() {
+  return new S;
+}
+
+void *alloc_overaligned_struct_with_extra_variable_alignment(int align) {
+  return new (std::align_val_t(align)) S;
+}
+void *alloc_overaligned_struct_with_extra_256_alignment(int align) {
+  return new (std::align_val_t(256)) S;
+}
+void *alloc_overaligned_struct_with_extra_255_alignment(int align) {
+  return new (std::align_val_t(255)) S;
+}
+
+std::align_val_t align_variable(int align) { return std::align_val_t

[PATCH] D73019: [Sema] Don't disallow placing `__attribute__((alloc_align(param_idx)))` on `std::align_val_t`-typed parameters

2020-01-23 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

In D73019#1836529 , @erichkeane wrote:

> This makes a lot of sense to me.


Thank you for the review!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73019/new/

https://reviews.llvm.org/D73019



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73019: [Sema] Don't disallow placing `__attribute__((alloc_align(param_idx)))` on `std::align_val_t`-typed parameters

2020-01-23 Thread Erich Keane via Phabricator via cfe-commits
erichkeane accepted this revision.
erichkeane added a comment.
This revision is now accepted and ready to land.

This makes a lot of sense to me.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73019/new/

https://reviews.llvm.org/D73019



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73019: [Sema] Don't disallow placing `__attribute__((alloc_align(param_idx)))` on `std::align_val_t`-typed parameters

2020-01-20 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri updated this revision to Diff 239179.
lebedev.ri added a comment.

NFC, more tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73019/new/

https://reviews.llvm.org/D73019

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) 
__attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+struct alignas(128) S {
+  S() {}
+};
+
+void *alloc_overaligned_struct() {
+  return new S;
+}
+
+void *alloc_overaligned_struct_with_extra_variable_alignment(int align) {
+  return new (std::align_val_t(align)) S;
+}
+void *alloc_overaligned_struct_with_extra_256_alignment(int align) {
+  return new (std::align_val_t(256)) S;
+}
+void *alloc_overaligned_struct_with_extra_255_alignment(int align) {
+  return new (std::align_val_t(255)) S;
+}
+
+std::align_val_t align_variable(int align) { return std::align_val_t(align); }
+std::align_val_t align_align16() { return std::align_val_t(16); }
+std::align_val_t align_align15() { return std::align_val_t(15); }
+
+// expected-no-diagnostics
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1669,7 +1669,8 @@
 return;
 
   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
-  if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) {
+  if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+  !Ty->isAlignValT()) {
 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
 << &TmpAttr
 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) __attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+struct alignas(128) S {
+  S() {}
+};
+
+void *alloc_overaligned_struct() {
+  return new S;
+}
+
+void *alloc_overaligned_struct_with_extra_variable_alignment(int align) {
+  return new (std::align_val_t(align)) S;
+}
+void *alloc_overaligned_struct_with_extra_256_alignment(int align) {
+  return new (std::align_val_t(256)) S;
+}
+void *alloc_overaligned_struct_with_extra_255_alignment(int align) {
+  return new (std::align_val_t(255)) S;
+}
+
+std::align_val_t align_variable(int align) { return std::align_va

[PATCH] D73019: [Sema] Don't disallow placing `__attribute__((alloc_align(param_idx)))` on `std::align_val_t`-typed parameters

2020-01-20 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri created this revision.
lebedev.ri added reviewers: erichkeane, rsmith, aaron.ballman, jdoerfert.
lebedev.ri added a project: clang.
lebedev.ri added a parent revision: D73006: [Codegen] If reasonable, 
materialize clang's `AllocAlignAttr` as llvm's Alignment Attribute on call-site 
function return value.
lebedev.ri added a child revision: D73020: [Sema] Perform call checking when 
building CXXNewExpr.

I kind-of understand why it is restricted to integer-typed arguments,
for general enum's the value passed is not nessesairly the alignment implied,
although one might say that user would know best.

But we clearly should whitelist `std::align_val_t`,
which is just a thin wrapper over `std::size_t`,
and is the C++ standard way of specifying alignment.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73019

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) 
__attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+std::align_val_t align_variable(int align) { return std::align_val_t(align); }
+std::align_val_t align_align16() { return std::align_val_t(16); }
+std::align_val_t align_align15() { return std::align_val_t(15); }
+
+// expected-no-diagnostics
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1669,7 +1669,8 @@
 return;
 
   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
-  if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) {
+  if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+  !Ty->isAlignValT()) {
 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
 << &TmpAttr
 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();


Index: clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/std-align-val-t-in-operator-new.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++11  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -faligned-allocation -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17  -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -faligned-allocation -fsyntax-only -verify %s
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+struct nothrow_t {};
+#if __cplusplus >= 201103L
+enum class align_val_t : size_t {};
+#else
+enum align_val_t {
+// We can't force an underlying type when targeting windows.
+#ifndef _WIN32
+  __zero = 0,
+  __max = (size_t)-1
+#endif
+};
+#endif
+} // namespace std
+
+void *operator new(std::size_t count, std::align_val_t al) __attribute__((alloc_align(2)));
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+struct OVERALIGNED A {
+  A();
+  int n[128];
+};
+
+void *ptr_variable(int align) { return new (std::align_val_t(align)) A; }
+void *ptr_align16() { return new (std::align_val_t(16)) A; }
+void *ptr_align15() { return new (std::align_val_t(15)) A; }
+
+std::align_val_t align_variable(int align) { return std::align_val_t(align); }
+std::align_val_t align_align16() { return std::align_val_t(16); }
+std::align_val_t align_align15() { return std::align_val_t(15); }
+
+// expected-no-diagnostics
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1669,7 +1669,8 @@
 return;
 
   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
-  if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) {
+  if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+