llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-driver

Author: Srividya Sundaram (srividya-sundaram)

<details>
<summary>Changes</summary>

SYCL is a C++-only programming model, but the Clang driver in llvm-project 
would silently accept .c files when -fsycl was specified and compile them as C. 
This could lead to confusing errors deep in compilation rather than a clear 
diagnostic at the driver level.

This patch implements the following behavior:

- A .c file passed with -fsycl is automatically treated as C++ and a warning is 
emitted: treating 'c' input as 'c++' when -fsycl is used
- Explicitly forcing -x c alongside -fsycl is now an error: '-x c' must not be 
used in conjunction with '-fsycl', which expects C++ source
- The same promotion applies to .h and preprocessed C files (.i), and to the 
MSVC-style /TC and /Tc flags
- The warning uses -Winvalid-command-line-argument, consistent with how 
llvm-project diagnoses other conflicting driver flag combinations.

---
Full diff: https://github.com/llvm/llvm-project/pull/200318.diff


3 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+5) 
- (modified) clang/lib/Driver/Driver.cpp (+33-2) 
- (added) clang/test/Driver/sycl-c-warn.c (+7) 


``````````diff
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..1439ba718b718 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,30 @@ 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 +3244,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 +3274,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..df21103898639
--- /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 
[-Winvalid-command-line-argument]
+
+// 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

``````````

</details>


https://github.com/llvm/llvm-project/pull/200318
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to