Skip to content

[clang] Reject VLAs in __is_layout_compatible() #87737

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 2 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def ext_vla_folded_to_constant : ExtWarn<
"variable length array folded to constant array as an extension">,
InGroup<GNUFoldingConstant>;
def err_vla_unsupported : Error<
"variable length arrays are not supported for %select{the current target|'%1'}0">;
"variable length arrays are not supported %select{for the current target|in '%1'}0">;
def err_vla_in_coroutine_unsupported : Error<
"variable length arrays in a coroutine are not supported">;
def note_vla_unsupported : Note<
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6026,6 +6026,9 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
return false;
}
case BTT_IsLayoutCompatible: {
if (LhsT->isVariableArrayType() || RhsT->isVariableArrayType())
Self.Diag(KeyLoc, diag::err_vla_unsupported)
<< 1 << tok::kw___is_layout_compatible;
return Self.IsLayoutCompatible(LhsT, RhsT);
}
default: llvm_unreachable("not a BTT");
Expand Down
10 changes: 6 additions & 4 deletions clang/test/SemaCXX/type-traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ void is_bounded_array(int n) {
static_assert(!__is_bounded_array(cvoid *));

int t32[n];
(void)__is_bounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_bounded_array'}}
(void)__is_bounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported in '__is_bounded_array'}}
}

void is_unbounded_array(int n) {
Expand Down Expand Up @@ -772,7 +772,7 @@ void is_unbounded_array(int n) {
static_assert(!__is_unbounded_array(cvoid *));

int t32[n];
(void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_unbounded_array'}}
(void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported in '__is_unbounded_array'}}
}

void is_referenceable() {
Expand Down Expand Up @@ -1741,8 +1741,10 @@ void is_layout_compatible(int n)
static_assert(!__is_layout_compatible(unsigned char, signed char));
static_assert(__is_layout_compatible(int[], int[]));
static_assert(__is_layout_compatible(int[2], int[2]));
static_assert(!__is_layout_compatible(int[n], int[2])); // FIXME: VLAs should be rejected
static_assert(!__is_layout_compatible(int[n], int[n])); // FIXME: VLAs should be rejected
static_assert(!__is_layout_compatible(int[n], int[2]));
// expected-error@-1 {{variable length arrays are not supported in '__is_layout_compatible'}}
static_assert(!__is_layout_compatible(int[n], int[n]));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think where we ended up is:

  1. Reject incomplete types (still needs to be done)
  2. Reject VLAs (done, looks good)
  3. FAMs are accepted (no changes needed)

So I think you should implement #1 and add tests for it, then add tests for #3, and I think that finishes this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recognize that discussion has spiraled out of VLAs into incomplete types and flexible array members, but can I keep the original scope of this PR, focusing on just VLAs?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with splitting the work across multiple patches so long as we get to the desired end state (or have issues filed to track what that end state should be).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, other items will be addressed in subsequent PRs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think focusing on VLAs here is fine, that was the original scope and I don't see an urgent need to expand it here.

// expected-error@-1 {{variable length arrays are not supported in '__is_layout_compatible'}}
static_assert(__is_layout_compatible(int&, int&));
static_assert(!__is_layout_compatible(int&, char&));
static_assert(__is_layout_compatible(void(int), void(int)));
Expand Down