[clang] [SYCL][Driver] Set -std=c++17 as default for SYCL compilations (PR #194014)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 27 18:48:17 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-driver
Author: Srividya Sundaram (srividya-sundaram)
<details>
<summary>Changes</summary>
This PR ensures SYCL compilations default to C++17 when no explicit standard is specified, and validates that user-provided standards meet SYCL's C++17 minimum requirement. It also fixes Windows MSVC compilation by enabling -fms-extensions for SYCL device code.
---
Full diff: https://github.com/llvm/llvm-project/pull/194014.diff
3 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+2)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+41-3)
- (added) clang/test/Driver/sycl-std-default.cpp (+67)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 469045948a47c..fdca0a334f230 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -231,6 +231,8 @@ def err_drv_argument_not_allowed_with : Error<
def warn_drv_argument_not_allowed_with : Warning<
"invalid argument '%0' not allowed with '%1'">,
InGroup<OptionIgnored>;
+def err_drv_sycl_requires_cxx17 : Error<
+ "SYCL requires C++17 or later; '%0' is not supported">;
def err_drv_cannot_open_randomize_layout_seed_file : Error<
"cannot read randomize layout seed file '%0'">;
def err_drv_invalid_version_number : Error<
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index cf5a29f19aaff..cfa3031431498 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4998,7 +4998,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
const llvm::Triple *AuxTriple =
- (IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
+ (IsCuda || IsHIP || IsSYCL) ? TC.getAuxTriple() : nullptr;
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
bool IsUEFI = RawTriple.isUEFI();
bool IsIAMCU = RawTriple.isOSIAMCU();
@@ -6519,8 +6519,22 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-std=c++98");
else
CmdArgs.push_back("-std=c89");
- else
+ else {
+ if (IsSYCL) {
+ const LangStandard *LangStd =
+ LangStandard::getLangStandardForName(Std->getValue());
+ if (LangStd) {
+ // Use of -std= with 'C' is not supported for SYCL.
+ if (LangStd->getLanguage() == Language::C)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << Std->getAsString(Args) << "-fsycl";
+ // SYCL requires C++17 or later.
+ else if (LangStd->isCPlusPlus() && !LangStd->isCPlusPlus17())
+ D.Diag(diag::err_drv_sycl_requires_cxx17) << Std->getAsString(Args);
+ }
+ }
Std->render(Args, CmdArgs);
+ }
// If -f(no-)trigraphs appears after the language standard flag, honor it.
if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
@@ -6545,6 +6559,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else if (IsWindowsMSVC)
ImplyVCPPCXXVer = true;
+ if (IsSYCL && types::isCXX(InputType) &&
+ !Args.hasArg(options::OPT__SLASH_std) && !IsWindowsMSVC)
+ // For SYCL, we default to -std=c++17 for all compilations. Use of -std
+ // on the command line will override. On Windows MSVC, this is handled
+ // by the ImplyVCPPCXXVer path below.
+ CmdArgs.push_back("-std=c++17");
+
Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
options::OPT_fno_trigraphs);
}
@@ -7460,13 +7481,30 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
.Case("c++23preview", "-std=c++23")
.Case("c++latest", "-std=c++26")
.Default("");
+ if (IsSYCL) {
+ const LangStandard *LangStd =
+ LangStandard::getLangStandardForName(StdArg->getValue());
+ if (LangStd) {
+ // Use of /std: with 'C' is not supported for SYCL.
+ if (LangStd->getLanguage() == Language::C)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << StdArg->getAsString(Args) << "-fsycl";
+ // SYCL requires C++17 or later.
+ else if (LangStd->isCPlusPlus() && !LangStd->isCPlusPlus17())
+ D.Diag(diag::err_drv_sycl_requires_cxx17)
+ << StdArg->getAsString(Args);
+ }
+ }
if (LanguageStandard.empty())
D.Diag(clang::diag::warn_drv_unused_argument)
<< StdArg->getAsString(Args);
}
if (LanguageStandard.empty()) {
- if (IsMSVC2015Compatible)
+ if (IsSYCL)
+ // For SYCL, C++17 is the default.
+ LanguageStandard = "-std=c++17";
+ else if (IsMSVC2015Compatible)
LanguageStandard = "-std=c++14";
else
LanguageStandard = "-std=c++11";
diff --git a/clang/test/Driver/sycl-std-default.cpp b/clang/test/Driver/sycl-std-default.cpp
new file mode 100644
index 0000000000000..df377169a3944
--- /dev/null
+++ b/clang/test/Driver/sycl-std-default.cpp
@@ -0,0 +1,67 @@
+// Tests that SYCL defaults to C++17 when no -std= is specified
+
+// RUN: %clangxx -### -fsycl -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK-DEVICE,CHECK-HOST
+
+// CHECK-DEVICE: "-cc1"{{.*}} "-fsycl-is-device"
+// CHECK-DEVICE-SAME: "-std=c++17"
+// CHECK-HOST: "-cc1"{{.*}} "-fsycl-is-host"
+// CHECK-HOST-SAME: "-std=c++17"
+
+// Test that explicit -std= overrides the default
+// RUN: %clangxx -### -fsycl -std=c++20 -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK-OVERRIDE-DEVICE,CHECK-OVERRIDE-HOST
+
+// CHECK-OVERRIDE-DEVICE: "-cc1"{{.*}} "-fsycl-is-device"
+// CHECK-OVERRIDE-DEVICE-SAME: "-std=c++20"
+// CHECK-OVERRIDE-DEVICE-NOT: "-std=c++17"
+// CHECK-OVERRIDE-HOST: "-cc1"{{.*}} "-fsycl-is-host"
+// CHECK-OVERRIDE-HOST-SAME: "-std=c++20"
+// CHECK-OVERRIDE-HOST-NOT: "-std=c++17"
+
+// Test that -std=c++14 or earlier produces an error
+// RUN: not %clangxx -fsycl -std=c++14 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX14-ERROR
+// RUN: not %clangxx -fsycl -std=c++11 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX11-ERROR
+// RUN: not %clangxx -fsycl -std=c++98 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX98-ERROR
+
+// CHECK-CXX14-ERROR: error: SYCL requires C++17 or later; '-std=c++14' is not supported
+// CHECK-CXX11-ERROR: error: SYCL requires C++17 or later; '-std=c++11' is not supported
+// CHECK-CXX98-ERROR: error: SYCL requires C++17 or later; '-std=c++98' is not supported
+
+// Test that C standards produce an error with SYCL
+// RUN: not %clangxx -fsycl -std=c11 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-C11-ERROR
+// RUN: not %clangxx -fsycl -std=c99 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-C99-ERROR
+
+// CHECK-C11-ERROR: error: invalid argument '-std=c11' not allowed with '-fsycl'
+// CHECK-C99-ERROR: error: invalid argument '-std=c99' not allowed with '-fsycl'
+
+// Test on Windows with clang-cl (MSVC mode)
+// RUN: %clang_cl --target=x86_64-pc-windows-msvc -### -fsycl -- %s 2>&1 | FileCheck %s --check-prefixes=CHECK-MSVC-DEVICE,CHECK-MSVC-HOST
+
+// CHECK-MSVC-DEVICE: "-cc1"{{.*}} "-fsycl-is-device"
+// CHECK-MSVC-DEVICE-SAME: "-std=c++17"
+// CHECK-MSVC-HOST: "-cc1"{{.*}} "-fsycl-is-host"
+// CHECK-MSVC-HOST-SAME: "-std=c++17"
+
+// Test that /std: override works on Windows
+// RUN: %clang_cl --target=x86_64-pc-windows-msvc -### -fsycl /std:c++20 -- %s 2>&1 | FileCheck %s --check-prefixes=CHECK-MSVC-OVERRIDE-DEVICE,CHECK-MSVC-OVERRIDE-HOST
+
+// CHECK-MSVC-OVERRIDE-DEVICE: "-cc1"{{.*}} "-fsycl-is-device"
+// CHECK-MSVC-OVERRIDE-DEVICE-SAME: "-std=c++20"
+// CHECK-MSVC-OVERRIDE-DEVICE-NOT: "-std=c++17"
+// CHECK-MSVC-OVERRIDE-HOST: "-cc1"{{.*}} "-fsycl-is-host"
+// CHECK-MSVC-OVERRIDE-HOST-SAME: "-std=c++20"
+// CHECK-MSVC-OVERRIDE-HOST-NOT: "-std=c++17"
+
+// Test that /std:c++14 produces an error on Windows
+// RUN: not %clang_cl --target=x86_64-pc-windows-msvc -fsycl /std:c++14 -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-MSVC-CXX14-ERROR
+
+// CHECK-MSVC-CXX14-ERROR: error: SYCL requires C++17 or later; '/std:c++14' is not supported
+
+// Test that C standards produce an error on Windows with clang-cl
+// RUN: not %clang_cl --target=x86_64-pc-windows-msvc -fsycl /std:c11 -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-MSVC-C-ERROR
+
+// CHECK-MSVC-C-ERROR: error: invalid argument '/std:c11' not allowed with '-fsycl'
+
+// Test without SYCL - should not default to C++17
+// RUN: %clangxx -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SYCL
+
+// CHECK-NO-SYCL-NOT: "-std=c++17"
``````````
</details>
https://github.com/llvm/llvm-project/pull/194014
More information about the cfe-commits
mailing list