Skip to content

[SYCL] Make sub_group non-user-constructible in preview mode - #23042

Open
KornevNikita wants to merge 2 commits into
intel:syclfrom
KornevNikita:upd-sg-ctor
Open

[SYCL] Make sub_group non-user-constructible in preview mode#23042
KornevNikita wants to merge 2 commits into
intel:syclfrom
KornevNikita:upd-sg-ctor

Conversation

@KornevNikita

Copy link
Copy Markdown
Contributor

SYCL 2020 section 4.9.1.8 specifies sycl::sub_group with a deleted default
constructor, but the implementation declared it protected and defaulted
instead. That is not equivalent: a constructor that is defaulted on its first
declaration is not user-provided, so in C++17 sub_group remained an
aggregate and sycl::sub_group{} was a well-formed aggregate initialization
that bypassed the access check altogether:

// Compiles today with -std=c++17, which is the default:
auto sg = sycl::sub_group{};

This patch deletes the default constructor and adds a protected one taking a
private tag. Being user-provided, it also makes the class a non-aggregate,
which closes the C++17 loophole. sub_group objects are now created through
that constructor in nd_item::get_sub_group() and
ext::oneapi::this_work_item::get_sub_group(), both of which are already
friends.

Applications may rely on the current permissive behavior, so the change is
guarded by __INTEL_PREVIEW_BREAKING_CHANGES.

The deprecated ext::oneapi::sub_group also stops initializing its base
through a private default constructor: copy-initializing the base works in
both modes and needs no guard.

Testing

New sycl/test/basic_tests/sub_group_interface.cpp checks the SYCL 2020
synopsis, the common by-value semantics, and that the class can be constructed
neither directly nor as an aggregate. It runs in four configurations:
{C++17, C++20} x {default, -fpreview-breaking-changes}.

Verified that legitimate ways of obtaining a sub-group still compile in all
four configurations (nd_item::get_sub_group(), the free function queries,
khr::this_sub_group(), copy/assign/compare, implicit conversion to the
deprecated ext::oneapi::sub_group, group algorithms), and that
sycl::sub_group{} still compiles outside of preview mode.

🤖 Generated with Claude Code

KornevNikita and others added 2 commits August 27, 2026 14:48
SYCL 2020 section 4.9.1.8 specifies sycl::sub_group with a deleted default
constructor, but the implementation declared it protected and defaulted
instead. That is not equivalent: a constructor that is defaulted on its first
declaration is not user-provided, so in C++17 sub_group remained an aggregate
and `sycl::sub_group{}` was a well-formed aggregate initialization, bypassing
the access check altogether.

Delete the default constructor and add a protected one taking a private tag.
Being user-provided, it also makes the class a non-aggregate, which closes the
C++17 loophole. sub_group objects are now created through that constructor in
nd_item::get_sub_group() and ext::oneapi::this_work_item::get_sub_group(),
both of which are already friends.

Applications may rely on the current permissive behavior, so the change is
guarded by __INTEL_PREVIEW_BREAKING_CHANGES.

Also stop the deprecated ext::oneapi::sub_group from initializing its base
through a private default constructor: copy-initializing the base works in
both modes and needs no guard.

Add a conformance test checking the SYCL 2020 synopsis, the common by-value
semantics, and that the class can be constructed neither directly nor as an
aggregate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@KornevNikita
KornevNikita marked this pull request as ready for review August 28, 2026 16:29
@KornevNikita
KornevNikita requested a review from a team as a code owner August 28, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant