Skip to content

[clang] Support __is_trivially_copyable(int()&)==false #81298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 5, 2024
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ Bug Fixes to C++ Support
Fixes (`#82249 <https://github.com/llvm/llvm-project/issues/82249>` _)
- Fixed a bug where abbreviated function templates would append their invented template parameters to
an empty template parameter lists.
- Fix parsing of abominable function types inside type traits.
Fixes (`#77585 <https://github.com/llvm/llvm-project/issues/77585>`_)
- Clang now classifies aggregate initialization in C++17 and newer as constant
or non-constant more accurately. Previously, only a subset of the initializer
elements were considered, misclassifying some initializers as constant. Fixes
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3908,7 +3908,10 @@ ExprResult Parser::ParseTypeTrait() {
SmallVector<ParsedType, 2> Args;
do {
// Parse the next type.
TypeResult Ty = ParseTypeName();
TypeResult Ty =
ParseTypeName(/*SourceRange=*/nullptr,
getLangOpts().CPlusPlus ? DeclaratorContext::TemplateArg
: DeclaratorContext::TypeName);
if (Ty.isInvalid()) {
Parens.skipToEnd();
return ExprError();
Expand Down Expand Up @@ -3950,7 +3953,8 @@ ExprResult Parser::ParseArrayTypeTrait() {
if (T.expectAndConsume())
return ExprError();

TypeResult Ty = ParseTypeName();
TypeResult Ty =
ParseTypeName(/*SourceRange=*/nullptr, DeclaratorContext::TemplateArg);
if (Ty.isInvalid()) {
SkipUntil(tok::comma, StopAtSemi);
SkipUntil(tok::r_paren, StopAtSemi);
Expand Down
9 changes: 5 additions & 4 deletions clang/test/Sema/static-assert.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c11 -Wgnu-folding-constant -fsyntax-only -verify %s
// RUN: %clang_cc1 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms %s
// RUN: %clang_cc1 -std=c99 -pedantic -Wgnu-folding-constant -fsyntax-only -verify=expected,ext %s
// RUN: %clang_cc1 -std=c11 -Wgnu-folding-constant -fsyntax-only -verify=expected,c %s
// RUN: %clang_cc1 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms,c %s
// RUN: %clang_cc1 -std=c99 -pedantic -Wgnu-folding-constant -fsyntax-only -verify=expected,ext,c %s
// RUN: %clang_cc1 -xc++ -std=c++11 -pedantic -fsyntax-only -verify=expected,ext,cxx %s

_Static_assert("foo", "string is nonzero"); // ext-warning {{'_Static_assert' is a C11 extension}}
Expand Down Expand Up @@ -57,7 +57,8 @@ UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; // ext-warning 3 {{'_Static_
typedef UNION(char, short) U3; // expected-error {{static assertion failed due to requirement 'sizeof(char) == sizeof(short)': type size mismatch}} \
// expected-note{{evaluates to '1 == 2'}} \
// ext-warning 3 {{'_Static_assert' is a C11 extension}}
typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \
typedef UNION(float, 0.5f) U4; // c-error {{expected a type}} \
// cxx-error {{type name requires a specifier or qualifier}} \
// ext-warning 3 {{'_Static_assert' is a C11 extension}}

// After defining the assert macro in MS-compatibility mode, we should
Expand Down
3 changes: 3 additions & 0 deletions clang/test/SemaCXX/type-traits-nonobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
static_assert(!__is_pod(void), "");
static_assert(!__is_pod(int&), "");
static_assert(!__is_pod(int()), "");
static_assert(!__is_pod(int()&), "");

static_assert(!__is_trivially_copyable(void), "");
static_assert(!__is_trivially_copyable(int&), "");
static_assert(!__is_trivially_copyable(int()), "");
static_assert(!__is_trivially_copyable(int()&), "");

static_assert(!__is_trivially_relocatable(void), "");
static_assert(!__is_trivially_relocatable(int&), "");
static_assert(!__is_trivially_relocatable(int()), "");
static_assert(!__is_trivially_relocatable(int()&), "");