https://github.com/srividya-sundaram updated https://github.com/llvm/llvm-project/pull/200318
>From 928d8589b0b4188aaa9a8fb8bfb5aaa7a9194f5e Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Tue, 26 May 2026 10:06:00 -0700 Subject: [PATCH 01/13] [Driver][SYCL] Verify that a .c file compiled with -fsycl is treated as C++ with a warning --- .../clang/Basic/DiagnosticDriverKinds.td | 5 ++++ clang/lib/Driver/Driver.cpp | 26 +++++++++++++++++-- clang/test/Driver/sycl-c-warn.c | 7 +++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 clang/test/Driver/sycl-c-warn.c diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 020014dabacfd..9a90b03c45b25 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -533,6 +533,11 @@ def warn_drv_overriding_complex_range : Warning< def warn_drv_treating_input_as_cxx : Warning< "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">, InGroup<Deprecated>; +def warn_drv_fsycl_with_c_type : Warning< + "treating '%0' input as '%1' when -fsycl is used">, + InGroup<InvalidCommandLineArgument>; +def err_drv_fsycl_with_c_type : Error< + "'%0' must not be used in conjunction with '-fsycl', which expects C++ source">; def warn_drv_pch_not_first_include : Warning< "precompiled header '%0' was ignored because '%1' is not first '-include'">; def warn_drv_pch_ignoring_gch_file : Warning< diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index ed3ddd130d6c7..bd30512ce9265 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3070,12 +3070,13 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // actually use it, so we warn about unused -x arguments. types::ID InputType = types::TY_Nothing; Arg *InputTypeArg = nullptr; + bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false); // The last /TC or /TP option sets the input type to C or C++ globally. if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { InputTypeArg = TCTP; - InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) + InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL ? types::TY_C : types::TY_CXX; @@ -3142,6 +3143,21 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (const char *Ext = strrchr(Value, '.')) Ty = TC.LookupTypeForExtension(Ext + 1); + // For SYCL, convert C-type sources to C++-type sources. + if (IsSYCL) { + types::ID OldTy = Ty; + switch (Ty) { + case types::TY_C: Ty = types::TY_CXX; break; + case types::TY_CHeader: Ty = types::TY_CXXHeader; break; + case types::TY_PP_C: Ty = types::TY_PP_CXX; break; + case types::TY_PP_CHeader: Ty = types::TY_PP_CXXHeader; break; + default: break; + } + if (OldTy != Ty) + Diag(clang::diag::warn_drv_fsycl_with_c_type) + << getTypeName(OldTy) << getTypeName(Ty); + } + if (Ty == types::TY_INVALID) { if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics)) Ty = types::TY_CXX; @@ -3219,7 +3235,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (DiagnoseInputExistence(Value, types::TY_C, /*TypoCorrect=*/false)) { Arg *InputArg = makeInputArg(Args, Opts, A->getValue()); - Inputs.push_back(std::make_pair(types::TY_C, InputArg)); + Inputs.push_back( + std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg)); } A->claim(); } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { @@ -3248,6 +3265,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, InputType = types::TY_Object; } + // Emit an error if C compilation is forced in -fsycl mode. + if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C || + InputType == types::TY_CHeader)) + Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args); + // If the user has put -fmodule-header{,=} then we treat C++ headers as // header unit inputs. So we 'promote' -xc++-header appropriately. if (InputType == types::TY_CXXHeader && hasHeaderMode()) diff --git a/clang/test/Driver/sycl-c-warn.c b/clang/test/Driver/sycl-c-warn.c new file mode 100644 index 0000000000000..4f3474add0f1c --- /dev/null +++ b/clang/test/Driver/sycl-c-warn.c @@ -0,0 +1,7 @@ +// Verify that a .c file compiled with -fsycl is treated as C++ with a warning. +// RUN: %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix WARN %s +// WARN: warning: treating 'c' input as 'c++' when -fsycl is used + +// Verify that explicitly forcing -x c with -fsycl is an error. +// RUN: %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR %s +// ERR: error: '-x c' must not be used in conjunction with '-fsycl', which expects C++ source >From bb2c790e47038d113f01bf867a480b0d74ebe8e0 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Thu, 28 May 2026 20:01:57 -0700 Subject: [PATCH 02/13] Update test. --- clang/test/Driver/sycl-c-warn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/sycl-c-warn.c b/clang/test/Driver/sycl-c-warn.c index 4f3474add0f1c..df21103898639 100644 --- a/clang/test/Driver/sycl-c-warn.c +++ b/clang/test/Driver/sycl-c-warn.c @@ -1,7 +1,7 @@ // Verify that a .c file compiled with -fsycl is treated as C++ with a warning. // RUN: %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix WARN %s -// WARN: warning: treating 'c' input as 'c++' when -fsycl is used +// WARN: warning: treating 'c' input as 'c++' when -fsycl is used [-Winvalid-command-line-argument] // Verify that explicitly forcing -x c with -fsycl is an error. -// RUN: %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR %s +// RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR %s // ERR: error: '-x c' must not be used in conjunction with '-fsycl', which expects C++ source >From cc232aa8017621757ebabdf7dc1f1fb93b27ec19 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Thu, 28 May 2026 20:08:28 -0700 Subject: [PATCH 03/13] clang format --- clang/lib/Driver/Driver.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index bd30512ce9265..1439ba718b718 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3147,11 +3147,20 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (IsSYCL) { types::ID OldTy = Ty; switch (Ty) { - case types::TY_C: Ty = types::TY_CXX; break; - case types::TY_CHeader: Ty = types::TY_CXXHeader; break; - case types::TY_PP_C: Ty = types::TY_PP_CXX; break; - case types::TY_PP_CHeader: Ty = types::TY_PP_CXXHeader; break; - default: break; + case types::TY_C: + Ty = types::TY_CXX; + break; + case types::TY_CHeader: + Ty = types::TY_CXXHeader; + break; + case types::TY_PP_C: + Ty = types::TY_PP_CXX; + break; + case types::TY_PP_CHeader: + Ty = types::TY_PP_CXXHeader; + break; + default: + break; } if (OldTy != Ty) Diag(clang::diag::warn_drv_fsycl_with_c_type) >From 59ffd02a26b9abfa05999e8cda57c9e4ea48f5d5 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 29 May 2026 08:38:55 -0700 Subject: [PATCH 04/13] [Driver][SYCL] Reuse existing C-to-C++ input promotion for -fsycl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of adding SYCL-specific diagnostics and a duplicate type-promotion switch, extend the existing CCCIsCXX() path in BuildInputs to also trigger when -fsycl is active. This reuses types::lookupCXXTypeForCType() for the C→C++ type promotion and warn_drv_treating_input_as_cxx for the warning. The -x c error case is similarly replaced with the generic err_drv_argument_not_allowed_with diagnostic. --- .../clang/Basic/DiagnosticDriverKinds.td | 5 ---- clang/lib/Driver/Driver.cpp | 30 +++---------------- clang/test/Driver/sycl-c-warn.c | 4 +-- 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 9a90b03c45b25..020014dabacfd 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -533,11 +533,6 @@ def warn_drv_overriding_complex_range : Warning< def warn_drv_treating_input_as_cxx : Warning< "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">, InGroup<Deprecated>; -def warn_drv_fsycl_with_c_type : Warning< - "treating '%0' input as '%1' when -fsycl is used">, - InGroup<InvalidCommandLineArgument>; -def err_drv_fsycl_with_c_type : Error< - "'%0' must not be used in conjunction with '-fsycl', which expects C++ source">; def warn_drv_pch_not_first_include : Warning< "precompiled header '%0' was ignored because '%1' is not first '-include'">; def warn_drv_pch_ignoring_gch_file : Warning< diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 1439ba718b718..4b62963270b96 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3143,30 +3143,6 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (const char *Ext = strrchr(Value, '.')) Ty = TC.LookupTypeForExtension(Ext + 1); - // For SYCL, convert C-type sources to C++-type sources. - if (IsSYCL) { - types::ID OldTy = Ty; - switch (Ty) { - case types::TY_C: - Ty = types::TY_CXX; - break; - case types::TY_CHeader: - Ty = types::TY_CXXHeader; - break; - case types::TY_PP_C: - Ty = types::TY_PP_CXX; - break; - case types::TY_PP_CHeader: - Ty = types::TY_PP_CXXHeader; - break; - default: - break; - } - if (OldTy != Ty) - Diag(clang::diag::warn_drv_fsycl_with_c_type) - << getTypeName(OldTy) << getTypeName(Ty); - } - if (Ty == types::TY_INVALID) { if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics)) Ty = types::TY_CXX; @@ -3180,7 +3156,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // If the driver is invoked as C++ compiler (like clang++ or c++) it // should autodetect some input files as C++ for g++ compatibility. - if (CCCIsCXX()) { + // -fsycl also requires C++ sources, so apply the same promotion. + if (CCCIsCXX() || IsSYCL) { types::ID OldTy = Ty; Ty = types::lookupCXXTypeForCType(Ty); @@ -3277,7 +3254,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // Emit an error if C compilation is forced in -fsycl mode. if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C || InputType == types::TY_CHeader)) - Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args); + Diag(clang::diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "-fsycl"; // If the user has put -fmodule-header{,=} then we treat C++ headers as // header unit inputs. So we 'promote' -xc++-header appropriately. diff --git a/clang/test/Driver/sycl-c-warn.c b/clang/test/Driver/sycl-c-warn.c index df21103898639..9de4067daaa53 100644 --- a/clang/test/Driver/sycl-c-warn.c +++ b/clang/test/Driver/sycl-c-warn.c @@ -1,7 +1,7 @@ // Verify that a .c file compiled with -fsycl is treated as C++ with a warning. // RUN: %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix WARN %s -// WARN: warning: treating 'c' input as 'c++' when -fsycl is used [-Winvalid-command-line-argument] +// WARN: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated] // Verify that explicitly forcing -x c with -fsycl is an error. // RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR %s -// ERR: error: '-x c' must not be used in conjunction with '-fsycl', which expects C++ source +// ERR: error: invalid argument '-x c' not allowed with '-fsycl' >From 68263e2be3d902d56e7864b312ca34c1a23e5b32 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Tue, 2 Jun 2026 18:02:29 -0700 Subject: [PATCH 05/13] [Driver][SYCL] Error on C inputs when compiling with -fsycl -fsycl requires C++ source files. Rather than silently promoting C inputs to C++ (which could mask issues like -std=c17 or other C-specific flags being ignored), emit an error when a C-type file is detected, whether via file extension or explicit -x c. The check is placed before the CCCIsCXX() promotion block since -fsycl implies C++ mode and would otherwise promote TY_C to TY_CXX before the check fires. Reuses the existing err_drv_argument_not_allowed_with diagnostic to avoid adding SYCL-specific diagnostics. --- clang/lib/Driver/Driver.cpp | 9 +++++++-- clang/test/Driver/sycl-c-warn.c | 12 ++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 4b62963270b96..c7c88f2891c91 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3154,10 +3154,15 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Ty = types::TY_Object; } + // -fsycl requires C++ source; error if a C file is detected. + if (IsSYCL && (Ty == types::TY_C || Ty == types::TY_PP_C || + Ty == types::TY_CHeader || Ty == types::TY_PP_CHeader)) + Diag(clang::diag::err_drv_argument_not_allowed_with) + << Value << "-fsycl"; + // If the driver is invoked as C++ compiler (like clang++ or c++) it // should autodetect some input files as C++ for g++ compatibility. - // -fsycl also requires C++ sources, so apply the same promotion. - if (CCCIsCXX() || IsSYCL) { + if (CCCIsCXX()) { types::ID OldTy = Ty; Ty = types::lookupCXXTypeForCType(Ty); diff --git a/clang/test/Driver/sycl-c-warn.c b/clang/test/Driver/sycl-c-warn.c index 9de4067daaa53..28358ac0fe88d 100644 --- a/clang/test/Driver/sycl-c-warn.c +++ b/clang/test/Driver/sycl-c-warn.c @@ -1,7 +1,7 @@ -// Verify that a .c file compiled with -fsycl is treated as C++ with a warning. -// RUN: %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix WARN %s -// WARN: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated] +// Verify that a .c file compiled with -fsycl is an error. +// RUN: not %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix ERR %s +// ERR: error: invalid argument '{{.*}}sycl-c-warn.c' not allowed with '-fsycl' -// Verify that explicitly forcing -x c with -fsycl is an error. -// RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR %s -// ERR: error: invalid argument '-x c' not allowed with '-fsycl' +// Verify that explicitly forcing -x c with -fsycl is also an error. +// RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR_XC %s +// ERR_XC: error: invalid argument '-x c' not allowed with '-fsycl' >From 5224b3d90dbe3ea83c2f131df88affce2754d19d Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Tue, 2 Jun 2026 18:18:52 -0700 Subject: [PATCH 06/13] Add comment. --- clang/lib/Driver/Driver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index c7c88f2891c91..a9d326d60b7fa 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3076,6 +3076,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { InputTypeArg = TCTP; + // /TC forces C, but -fsycl requires C++; let the per-file check below + // handle the error rather than silently setting all inputs to TY_C. InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL ? types::TY_C : types::TY_CXX; >From 49d4f72a1a6e8cec31a29d74e33b7e654ab2814b Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Tue, 2 Jun 2026 18:27:23 -0700 Subject: [PATCH 07/13] Update affected tests to pass -x c++ explicitly when using -fsycl with .c files. --- clang/test/Driver/offload-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/offload-target.c b/clang/test/Driver/offload-target.c index 23a2cf26eb192..76d506c3dcf9a 100644 --- a/clang/test/Driver/offload-target.c +++ b/clang/test/Driver/offload-target.c @@ -1,4 +1,4 @@ -// RUN: %clang -### -fsycl --offload-targets=spirv64 -nogpuinc %s -ccc-print-bindings 2>&1 \ +// RUN: %clang -### -fsycl --offload-targets=spirv64 -nogpuinc -x c++ %s -ccc-print-bindings 2>&1 \ // RUN: | FileCheck %s -check-prefix=SYCL // SYCL: "spirv64" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[SYCL_BC:.+]]" >From 793e11bcdedd2136097a8a2a6eaafe2ec8a46cd8 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Wed, 3 Jun 2026 12:14:08 -0700 Subject: [PATCH 08/13] [Driver][SYCL] Error on C inputs when compiling with -fsycl Emit an error when a C-type input is detected under -fsycl, whether via file extension, -x c, or clang-cl /TC and /Tc flags. Reuses the existing err_drv_argument_not_allowed_with diagnostic to avoid SYCL-specific additions. --- clang/lib/Driver/Driver.cpp | 17 ++++++++++------- clang/test/Driver/sycl-c-warn.c | 4 ---- clang/test/Driver/sycl-force-c-input-error.cpp | 11 +++++++++++ 3 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 clang/test/Driver/sycl-force-c-input-error.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a9d326d60b7fa..d2b11c1e61387 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3076,9 +3076,10 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { InputTypeArg = TCTP; - // /TC forces C, but -fsycl requires C++; let the per-file check below - // handle the error rather than silently setting all inputs to TY_C. - InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL + if (TCTP->getOption().matches(options::OPT__SLASH_TC) && IsSYCL) + Diag(clang::diag::err_drv_argument_not_allowed_with) + << TCTP->getAsString(Args) << "-fsycl"; + InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) ? types::TY_C : types::TY_CXX; @@ -3225,11 +3226,13 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, } else if (A->getOption().matches(options::OPT__SLASH_Tc)) { StringRef Value = A->getValue(); - if (DiagnoseInputExistence(Value, types::TY_C, - /*TypoCorrect=*/false)) { + if (IsSYCL) + Diag(clang::diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "-fsycl"; + else if (DiagnoseInputExistence(Value, types::TY_C, + /*TypoCorrect=*/false)) { Arg *InputArg = makeInputArg(Args, Opts, A->getValue()); - Inputs.push_back( - std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg)); + Inputs.push_back(std::make_pair(types::TY_C, InputArg)); } A->claim(); } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { diff --git a/clang/test/Driver/sycl-c-warn.c b/clang/test/Driver/sycl-c-warn.c index 28358ac0fe88d..d741b9b692fea 100644 --- a/clang/test/Driver/sycl-c-warn.c +++ b/clang/test/Driver/sycl-c-warn.c @@ -1,7 +1,3 @@ // Verify that a .c file compiled with -fsycl is an error. // RUN: not %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix ERR %s // ERR: error: invalid argument '{{.*}}sycl-c-warn.c' not allowed with '-fsycl' - -// Verify that explicitly forcing -x c with -fsycl is also an error. -// RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR_XC %s -// ERR_XC: error: invalid argument '-x c' not allowed with '-fsycl' diff --git a/clang/test/Driver/sycl-force-c-input-error.cpp b/clang/test/Driver/sycl-force-c-input-error.cpp new file mode 100644 index 0000000000000..9958ed5ee5024 --- /dev/null +++ b/clang/test/Driver/sycl-force-c-input-error.cpp @@ -0,0 +1,11 @@ +// Verify that explicitly forcing -x c with -fsycl is an error. +// RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR_XC %s +// ERR_XC: error: invalid argument '-x c' not allowed with '-fsycl' + +// Verify that clang-cl /TC (forces all inputs to C) with -fsycl is an error. +// RUN: not %clang_cl -### -fsycl /TC %s 2>&1 | FileCheck -check-prefix ERR_TC %s +// ERR_TC: error: invalid argument '/TC' not allowed with '-fsycl' + +// Verify that clang-cl /Tc (forces a specific file to C) with -fsycl is an error. +// RUN: not %clang_cl -### -fsycl /Tc%s 2>&1 | FileCheck -check-prefix ERR_Tc %s +// ERR_Tc: error: invalid argument '/Tc{{.*}}sycl-force-c-input-error.cpp' not allowed with '-fsycl' >From 2c823383cfb04ac2d3c1615aca638b27cd78a057 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Sat, 6 Jun 2026 10:32:53 -0700 Subject: [PATCH 09/13] [Frontend][SYCL] Error on C inputs when compiling with -fsycl SYCL is a C++-based programming model and requires C++ source files. Enforce this invariant in the frontend by rejecting C inputs when SYCL mode is active, ensuring that LangOpts.SYCL implies LangOpts.CPlusPlus regardless of how the compiler is invoked. --- clang/lib/Driver/Driver.cpp | 23 ++----------------- clang/lib/Frontend/CompilerInvocation.cpp | 5 ++++ clang/test/Driver/sycl-c-warn.c | 3 --- .../test/Driver/sycl-force-c-input-error.cpp | 11 --------- clang/test/Frontend/sycl-c-input-error.cpp | 7 ++++++ 5 files changed, 14 insertions(+), 35 deletions(-) delete mode 100644 clang/test/Driver/sycl-c-warn.c delete mode 100644 clang/test/Driver/sycl-force-c-input-error.cpp create mode 100644 clang/test/Frontend/sycl-c-input-error.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index d2b11c1e61387..ed3ddd130d6c7 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3070,15 +3070,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // actually use it, so we warn about unused -x arguments. types::ID InputType = types::TY_Nothing; Arg *InputTypeArg = nullptr; - bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false); // The last /TC or /TP option sets the input type to C or C++ globally. if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { InputTypeArg = TCTP; - if (TCTP->getOption().matches(options::OPT__SLASH_TC) && IsSYCL) - Diag(clang::diag::err_drv_argument_not_allowed_with) - << TCTP->getAsString(Args) << "-fsycl"; InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) ? types::TY_C : types::TY_CXX; @@ -3157,12 +3153,6 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Ty = types::TY_Object; } - // -fsycl requires C++ source; error if a C file is detected. - if (IsSYCL && (Ty == types::TY_C || Ty == types::TY_PP_C || - Ty == types::TY_CHeader || Ty == types::TY_PP_CHeader)) - Diag(clang::diag::err_drv_argument_not_allowed_with) - << Value << "-fsycl"; - // If the driver is invoked as C++ compiler (like clang++ or c++) it // should autodetect some input files as C++ for g++ compatibility. if (CCCIsCXX()) { @@ -3226,11 +3216,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, } else if (A->getOption().matches(options::OPT__SLASH_Tc)) { StringRef Value = A->getValue(); - if (IsSYCL) - Diag(clang::diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-fsycl"; - else if (DiagnoseInputExistence(Value, types::TY_C, - /*TypoCorrect=*/false)) { + if (DiagnoseInputExistence(Value, types::TY_C, + /*TypoCorrect=*/false)) { Arg *InputArg = makeInputArg(Args, Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_C, InputArg)); } @@ -3261,12 +3248,6 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, InputType = types::TY_Object; } - // Emit an error if C compilation is forced in -fsycl mode. - if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C || - InputType == types::TY_CHeader)) - Diag(clang::diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-fsycl"; - // If the user has put -fmodule-header{,=} then we treat C++ headers as // header unit inputs. So we 'promote' -xc++-header appropriately. if (InputType == types::TY_CXXHeader && hasHeaderMode()) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 60749104252af..c1f2b3937cb07 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -635,6 +635,11 @@ static bool FixupInvocation(CompilerInvocation &Invocation, Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device" << "-fsycl-is-host"; + // SYCL requires C++; reject C inputs on both device and host. + if ((LangOpts.SYCLIsDevice || LangOpts.SYCLIsHost) && !LangOpts.CPlusPlus) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << GetInputKindName(IK) << "-fsycl"; + if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus) Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fgnu89-inline" << GetInputKindName(IK); diff --git a/clang/test/Driver/sycl-c-warn.c b/clang/test/Driver/sycl-c-warn.c deleted file mode 100644 index d741b9b692fea..0000000000000 --- a/clang/test/Driver/sycl-c-warn.c +++ /dev/null @@ -1,3 +0,0 @@ -// Verify that a .c file compiled with -fsycl is an error. -// RUN: not %clang -### -fsycl %s 2>&1 | FileCheck -check-prefix ERR %s -// ERR: error: invalid argument '{{.*}}sycl-c-warn.c' not allowed with '-fsycl' diff --git a/clang/test/Driver/sycl-force-c-input-error.cpp b/clang/test/Driver/sycl-force-c-input-error.cpp deleted file mode 100644 index 9958ed5ee5024..0000000000000 --- a/clang/test/Driver/sycl-force-c-input-error.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// Verify that explicitly forcing -x c with -fsycl is an error. -// RUN: not %clang -### -fsycl -x c %s 2>&1 | FileCheck -check-prefix ERR_XC %s -// ERR_XC: error: invalid argument '-x c' not allowed with '-fsycl' - -// Verify that clang-cl /TC (forces all inputs to C) with -fsycl is an error. -// RUN: not %clang_cl -### -fsycl /TC %s 2>&1 | FileCheck -check-prefix ERR_TC %s -// ERR_TC: error: invalid argument '/TC' not allowed with '-fsycl' - -// Verify that clang-cl /Tc (forces a specific file to C) with -fsycl is an error. -// RUN: not %clang_cl -### -fsycl /Tc%s 2>&1 | FileCheck -check-prefix ERR_Tc %s -// ERR_Tc: error: invalid argument '/Tc{{.*}}sycl-force-c-input-error.cpp' not allowed with '-fsycl' diff --git a/clang/test/Frontend/sycl-c-input-error.cpp b/clang/test/Frontend/sycl-c-input-error.cpp new file mode 100644 index 0000000000000..ef87bc1f2dba7 --- /dev/null +++ b/clang/test/Frontend/sycl-c-input-error.cpp @@ -0,0 +1,7 @@ +// Verify that cc1 -fsycl-is-device rejects C inputs. +// RUN: not %clang_cc1 -fsycl-is-device -triple spirv64-unknown-unknown -x c %s 2>&1 | FileCheck -check-prefix ERR_DEVICE %s +// ERR_DEVICE: error: invalid argument 'C' not allowed with '-fsycl' + +// Verify that cc1 -fsycl-is-host rejects C inputs. +// RUN: not %clang_cc1 -fsycl-is-host -triple x86_64-unknown-linux-gnu -x c %s 2>&1 | FileCheck -check-prefix ERR_HOST %s +// ERR_HOST: error: invalid argument 'C' not allowed with '-fsycl' >From 51b70c0fc6da8ff0ef8c5688a11235acc399f66f Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Sat, 6 Jun 2026 10:45:09 -0700 Subject: [PATCH 10/13] =?UTF-8?q?Added=20driver-level=20test=20exercising?= =?UTF-8?q?=20the=20full=20driver=20=E2=86=92=20cc1=20=E2=86=92=20frontend?= =?UTF-8?q?=20error=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clang/test/Driver/sycl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/test/Driver/sycl.cpp b/clang/test/Driver/sycl.cpp index 5c210c8c181da..e78b2a7593323 100644 --- a/clang/test/Driver/sycl.cpp +++ b/clang/test/Driver/sycl.cpp @@ -30,3 +30,7 @@ // RUN: %clangxx -### -fsycl -sycl-std=2017 --no-offloadlib -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OFFLOADLIB // RUN: %clang_cl -### -fsycl -sycl-std=2017 --no-offloadlib -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OFFLOADLIB // CHECK-NO-OFFLOADLIB-NOT: warning: unknown argument ignored in clang-cl: '--no-offloadlib' + +// Verify that -fsycl with a C input is an error (enforced in the frontend). +// RUN: not %clang -fsycl -x c %s 2>&1 | FileCheck %s --check-prefix=CHECK-C-INPUT +// CHECK-C-INPUT: error: invalid argument 'C' not allowed with '-fsycl' >From 46716e45952001a56e5c6ccfaf0a8348160d0104 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Sat, 6 Jun 2026 15:57:02 -0700 Subject: [PATCH 11/13] Update test. --- clang/test/CodeGenSYCL/filescope_asm.c | 2 +- clang/test/Headers/__cpuidex_conflict.c | 2 +- .../BuiltIns/generic_cast_to_ptr_explicit.c | 2 +- clang/unittests/Frontend/CompilerInvocationTest.cpp | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clang/test/CodeGenSYCL/filescope_asm.c b/clang/test/CodeGenSYCL/filescope_asm.c index 9c0d088ec0a2d..194e3b6158044 100644 --- a/clang/test/CodeGenSYCL/filescope_asm.c +++ b/clang/test/CodeGenSYCL/filescope_asm.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -x c++ -emit-llvm %s -o - | FileCheck %s // // Check that file-scope asm is ignored during device-side SYCL compilation. // diff --git a/clang/test/Headers/__cpuidex_conflict.c b/clang/test/Headers/__cpuidex_conflict.c index a928aa895c44d..0292801ddb943 100644 --- a/clang/test/Headers/__cpuidex_conflict.c +++ b/clang/test/Headers/__cpuidex_conflict.c @@ -8,7 +8,7 @@ // RUN: %clang_cc1 -DIS_STATIC="" -triple nvptx64-nvidia-cuda -aux-triple x86_64-unknown-linux-gnu -aux-target-cpu x86-64 -fcuda-is-device -x cuda %s -o - // RUN: %clang_cc1 -DIS_STATIC="" -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-linux-gnu -aux-target-cpu x86-64 -fcuda-is-device -x cuda %s -o - // RUN: %clang_cc1 -DIS_STATIC="" -triple spirv64 -aux-triple x86_64-unknown-linux-gnu -aux-target-cpu x86-64 -fcuda-is-device -x cuda %s -o - -// RUN: %clang_cc1 -DIS_STATIC="" -triple spirv64 -aux-triple x86_64-unknown-linux-gnu -aux-target-cpu x86-64 -fsycl-is-device %s -o - +// RUN: %clang_cc1 -DIS_STATIC="" -triple spirv64 -aux-triple x86_64-unknown-linux-gnu -aux-target-cpu x86-64 -fsycl-is-device -x c++ %s -o - typedef __SIZE_TYPE__ size_t; diff --git a/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c b/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c index 5a839961e20f5..7f3a3f46ca6da 100644 --- a/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c +++ b/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -O1 -triple spirv64 -fsycl-is-device -verify %s -o - +// RUN: %clang_cc1 -O1 -triple spirv64 -fsycl-is-device -x c++ -verify %s -o - // RUN: %clang_cc1 -O1 -triple spirv64 -verify %s -cl-std=CL3.0 -x cl -o - // RUN: %clang_cc1 -O1 -triple spirv32 -verify %s -cl-std=CL3.0 -x cl -o - diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp index 64d0f4c38f11c..939f7479214cc 100644 --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -638,7 +638,7 @@ TEST_F(CommandLineTest, ConditionalParsingIfNonsenseSyclStdArg) { } TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg1) { - const char *Args[] = {"-fsycl-is-device", "-sycl-std=121"}; + const char *Args[] = {"-fsycl-is-device", "-sycl-std=121", "-x", "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); @@ -655,7 +655,7 @@ TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg1) { } TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg2) { - const char *Args[] = {"-fsycl-is-device", "-sycl-std=1.2.1"}; + const char *Args[] = {"-fsycl-is-device", "-sycl-std=1.2.1", "-x", "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); @@ -672,7 +672,7 @@ TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg2) { } TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg3) { - const char *Args[] = {"-fsycl-is-device", "-sycl-std=sycl-1.2.1"}; + const char *Args[] = {"-fsycl-is-device", "-sycl-std=sycl-1.2.1", "-x", "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); @@ -689,7 +689,7 @@ TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg3) { } TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresentHost) { - const char *Args[] = {"-fsycl-is-host"}; + const char *Args[] = {"-fsycl-is-host", "-x", "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); @@ -704,7 +704,7 @@ TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresentHost) { } TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresentDevice) { - const char *Args[] = {"-fsycl-is-device"}; + const char *Args[] = {"-fsycl-is-device", "-x", "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); @@ -719,7 +719,7 @@ TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresentDevice) { } TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagPresent) { - const char *Args[] = {"-fsycl-is-device", "-sycl-std=2017"}; + const char *Args[] = {"-fsycl-is-device", "-sycl-std=2017", "-x", "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); >From f22e9bcbec1caf929ad65460b4809c2926b911a7 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Sat, 6 Jun 2026 16:37:27 -0700 Subject: [PATCH 12/13] Fix clang format. --- clang/unittests/Frontend/CompilerInvocationTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp index 939f7479214cc..887fbc5938333 100644 --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -672,7 +672,8 @@ TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg2) { } TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg3) { - const char *Args[] = {"-fsycl-is-device", "-sycl-std=sycl-1.2.1", "-x", "c++"}; + const char *Args[] = {"-fsycl-is-device", "-sycl-std=sycl-1.2.1", "-x", + "c++"}; CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); >From 0a7dd8d336eaf298a45755d2c42418a9cabdfe26 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Sun, 7 Jun 2026 15:58:18 -0700 Subject: [PATCH 13/13] Update SemaSPIRV tests to use -x c++ with -fsycl-is-device Add -x c++ to the -fsycl-is-device RUN lines in ids_and_ranges.c and subgroup-errors.c to comply with the new frontend check that rejects C inputs in SYCL mode. Use named check prefixes (cxx/cl) to keep separate expected-error annotations for C++ and OpenCL RUN lines, since the two modes produce different diagnostic wording for type mismatch errors. --- .../test/SemaSPIRV/BuiltIns/ids_and_ranges.c | 58 +++++++++---------- .../test/SemaSPIRV/BuiltIns/subgroup-errors.c | 18 +++--- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/clang/test/SemaSPIRV/BuiltIns/ids_and_ranges.c b/clang/test/SemaSPIRV/BuiltIns/ids_and_ranges.c index 0d98a552bb1b9..7db799dd816d1 100644 --- a/clang/test/SemaSPIRV/BuiltIns/ids_and_ranges.c +++ b/clang/test/SemaSPIRV/BuiltIns/ids_and_ranges.c @@ -1,77 +1,77 @@ -// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -fsycl-is-device -verify %s -o - -// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -verify %s -cl-std=CL3.0 -x cl -o - -// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv32 -verify %s -cl-std=CL3.0 -x cl -o - +// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -fsycl-is-device -x c++ -verify=cxx %s -o - +// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -verify=cl %s -cl-std=CL3.0 -x cl -o - +// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv32 -verify=cl %s -cl-std=CL3.0 -x cl -o - void test_num_workgroups(int* p) { __builtin_spirv_num_workgroups(0); - __builtin_spirv_num_workgroups(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_num_workgroups(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_num_workgroups(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_num_workgroups(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_num_workgroups(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_num_workgroups(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_workgroup_size(int* p) { __builtin_spirv_workgroup_size(0); - __builtin_spirv_workgroup_size(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_workgroup_size(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_workgroup_size(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_workgroup_size(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_workgroup_size(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_workgroup_size(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_workgroup_id(int* p) { __builtin_spirv_workgroup_id(0); - __builtin_spirv_workgroup_id(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_workgroup_id(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_workgroup_id(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_workgroup_id(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_workgroup_id(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_workgroup_id(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_local_invocation_id(int* p) { __builtin_spirv_local_invocation_id(0); - __builtin_spirv_local_invocation_id(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_local_invocation_id(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_local_invocation_id(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_local_invocation_id(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_local_invocation_id(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_local_invocation_id(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_global_invocation_id(int* p) { __builtin_spirv_global_invocation_id(0); - __builtin_spirv_global_invocation_id(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_global_invocation_id(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_global_invocation_id(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_global_invocation_id(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_global_invocation_id(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_global_invocation_id(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_global_size(int* p) { __builtin_spirv_global_size(0); - __builtin_spirv_global_size(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_global_size(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_global_size(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_global_size(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_global_size(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_global_size(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_global_offset(int* p) { __builtin_spirv_global_offset(0); - __builtin_spirv_global_offset(p); // expected-error{{incompatible pointer to integer conversion}} - __builtin_spirv_global_offset(0, 0); // expected-error{{too many arguments to function call, expected 1, have 2}} - __builtin_spirv_global_offset(); // expected-error{{too few arguments to function call, expected 1, have 0}} + __builtin_spirv_global_offset(p); // cxx-error{{cannot initialize a parameter of type 'int' with an lvalue of type 'int *'}} cl-error{{incompatible pointer to integer conversion}} + __builtin_spirv_global_offset(0, 0); // cxx-error{{too many arguments to function call, expected 1, have 2}} cl-error{{too many arguments to function call, expected 1, have 2}} + __builtin_spirv_global_offset(); // cxx-error{{too few arguments to function call, expected 1, have 0}} cl-error{{too few arguments to function call, expected 1, have 0}} } void test_subgroup_size() { __builtin_spirv_subgroup_size(); - __builtin_spirv_subgroup_size(0); // expected-error{{too many arguments to function call, expected 0, have 1}} + __builtin_spirv_subgroup_size(0); // cxx-error{{too many arguments to function call, expected 0, have 1}} cl-error{{too many arguments to function call, expected 0, have 1}} } void test_subgroup_max_size() { __builtin_spirv_subgroup_max_size(); - __builtin_spirv_subgroup_max_size(0); // expected-error{{too many arguments to function call, expected 0, have 1}} + __builtin_spirv_subgroup_max_size(0); // cxx-error{{too many arguments to function call, expected 0, have 1}} cl-error{{too many arguments to function call, expected 0, have 1}} } void test_num_subgroups() { __builtin_spirv_num_subgroups(); - __builtin_spirv_num_subgroups(0); // expected-error{{too many arguments to function call, expected 0, have 1}} + __builtin_spirv_num_subgroups(0); // cxx-error{{too many arguments to function call, expected 0, have 1}} cl-error{{too many arguments to function call, expected 0, have 1}} } void test_subgroup_id() { __builtin_spirv_subgroup_id(); - __builtin_spirv_subgroup_id(0); // expected-error{{too many arguments to function call, expected 0, have 1}} + __builtin_spirv_subgroup_id(0); // cxx-error{{too many arguments to function call, expected 0, have 1}} cl-error{{too many arguments to function call, expected 0, have 1}} } void test_subgroup_local_invocation_id() { __builtin_spirv_subgroup_local_invocation_id(); - __builtin_spirv_subgroup_local_invocation_id(0); // expected-error{{too many arguments to function call, expected 0, have 1}} + __builtin_spirv_subgroup_local_invocation_id(0); // cxx-error{{too many arguments to function call, expected 0, have 1}} cl-error{{too many arguments to function call, expected 0, have 1}} } diff --git a/clang/test/SemaSPIRV/BuiltIns/subgroup-errors.c b/clang/test/SemaSPIRV/BuiltIns/subgroup-errors.c index 95edf585dd45b..0e20d97334593 100644 --- a/clang/test/SemaSPIRV/BuiltIns/subgroup-errors.c +++ b/clang/test/SemaSPIRV/BuiltIns/subgroup-errors.c @@ -1,15 +1,15 @@ -// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -fsycl-is-device -verify %s -o - -// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -verify %s -cl-std=CL3.0 -x cl -o - -// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv32 -verify %s -cl-std=CL3.0 -x cl -o - +// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -fsycl-is-device -x c++ -verify=cxx %s -o - +// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv64 -verify=cl %s -cl-std=CL3.0 -x cl -o - +// RUN: %clang_cc1 -O1 -Wno-unused-value -triple spirv32 -verify=cl %s -cl-std=CL3.0 -x cl -o - typedef unsigned __attribute__((ext_vector_type(4))) int4; -void ballot(_Bool c) { +void ballot(bool c) { int4 x; x = __builtin_spirv_subgroup_ballot(c); x = __builtin_spirv_subgroup_ballot(1); - x = __builtin_spirv_subgroup_ballot(x); // expected-error{{parameter of incompatible type}} - int y = __builtin_spirv_subgroup_ballot(c); // expected-error{{with an expression of incompatible type}} + x = __builtin_spirv_subgroup_ballot(x); // cxx-error{{cannot initialize a parameter of type 'bool' with an lvalue of type 'int4'}} cl-error{{parameter of incompatible type}} + int y = __builtin_spirv_subgroup_ballot(c); // cxx-error{{cannot initialize a variable of type 'int' with an rvalue of type}} cl-error{{with an expression of incompatible type}} } void shuffle() { @@ -18,7 +18,7 @@ void shuffle() { int [[clang::ext_vector_type(1)]] v; (void)__builtin_spirv_subgroup_shuffle(x, x); (void)__builtin_spirv_subgroup_shuffle(f, f); - (void)__builtin_spirv_subgroup_shuffle(x, x, x); // expected-error{{too many arguments to function call, expected 2, have 3}} - (void)__builtin_spirv_subgroup_shuffle(v, f); // expected-error{{1st argument must be a scalar type}} - (void)__builtin_spirv_subgroup_shuffle(f, v); // expected-error{{to parameter of incompatible type}} + (void)__builtin_spirv_subgroup_shuffle(x, x, x); // cxx-error{{too many arguments to function call, expected 2, have 3}} cl-error{{too many arguments to function call, expected 2, have 3}} + (void)__builtin_spirv_subgroup_shuffle(v, f); // cxx-error{{1st argument must be a scalar type}} cl-error{{1st argument must be a scalar type}} + (void)__builtin_spirv_subgroup_shuffle(f, v); // cxx-error{{to parameter of incompatible type}} cl-error{{to parameter of incompatible type}} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
