Skip to content

[Clang][Driver] Warn on complex number range incompatibility with GCC #144468

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

s-watanabe314
Copy link
Contributor

This patch adds a warning for incompatible complex number behavior compared to GCC due to Clang's "last-flag-wins" rule.

Incompatibilities with GCC occur in the following seven cases. Clang uses the last specified option, but GCC uses an earlier specified option in these seven cases because it has a different option prioritization.

# Options Complex Division Algorithm in GCC 14.2.0 Complex Division Algorithm in Clang
1 -fcx-limited-range -fno-fast-math algebraic method runtime function call
2 -fcx-fortran-rules -fcx-limited-range Smith's method algebraic method
3 -fcx-fortran-rules -fno-cx-limited-range Smith's method runtime function call
4 -fcx-fortran-rules -ffast-math Smith's method algebraic method
5 -fcx-fortran-rules -fno-fast-math Smith's method runtime function call
6 -fno-cx-fortran-rules -fcx-limited-range runtime function call algebraic method
7 -fno-cx-fortran-rules -ffast-math runtime function call algebraic method

These were discussed at:
https://discourse.llvm.org/t/the-priority-of-fno-fast-math-regarding-complex-number-calculations/84679

This patch adds a warning for incompatible complex number behavior
compared to GCC due to Clang's "last-flag-wins" rule.

These were discussed at:
https://discourse.llvm.org/t/the-priority-of-fno-fast-math-regarding-complex-number-calculations/84679
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 17, 2025

@llvm/pr-subscribers-clang-driver

Author: Shunsuke Watanabe (s-watanabe314)

Changes

This patch adds a warning for incompatible complex number behavior compared to GCC due to Clang's "last-flag-wins" rule.

Incompatibilities with GCC occur in the following seven cases. Clang uses the last specified option, but GCC uses an earlier specified option in these seven cases because it has a different option prioritization.

# Options Complex Division Algorithm in GCC 14.2.0 Complex Division Algorithm in Clang
1 -fcx-limited-range -fno-fast-math algebraic method runtime function call
2 -fcx-fortran-rules -fcx-limited-range Smith's method algebraic method
3 -fcx-fortran-rules -fno-cx-limited-range Smith's method runtime function call
4 -fcx-fortran-rules -ffast-math Smith's method algebraic method
5 -fcx-fortran-rules -fno-fast-math Smith's method runtime function call
6 -fno-cx-fortran-rules -fcx-limited-range runtime function call algebraic method
7 -fno-cx-fortran-rules -ffast-math runtime function call algebraic method

These were discussed at:
https://discourse.llvm.org/t/the-priority-of-fno-fast-math-regarding-complex-number-calculations/84679


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

3 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+19)
  • (modified) clang/test/Driver/range.c (+33)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 20fb47237c56f..377509cfcf2cd 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -520,6 +520,9 @@ def warn_drv_math_errno_enabled_after_veclib: Warning<
   "math errno enabled by '%0' after it was implicitly disabled by '%1',"
   " this may limit the utilization of the vector library">,
   InGroup<MathErrnoEnabledWithVecLib>;
+def warn_drv_gcc_incompatible_complex_range_override: Warning<
+  "combination of '%0' and '%1' results in complex number calculations incompatible with GCC">,
+  InGroup<GccCompat>;
 
 def note_drv_command_failed_diag_msg : Note<
   "diagnostic msg: %0">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1d11be1d82be8..244c4c0848aa6 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2915,6 +2915,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
       } else {
         if (GccRangeComplexOption != "-fno-cx-limited-range")
           EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-limited-range");
+        // Warn about complex range option overrides incompatible with GCC.
+        if (GccRangeComplexOption == "-fcx-fortran-rules" ||
+            GccRangeComplexOption == "-fno-cx-fortran-rules")
+          D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+              << GccRangeComplexOption << A->getSpelling();
       }
       GccRangeComplexOption = "-fcx-limited-range";
       LastComplexRangeOption = A->getSpelling();
@@ -2929,6 +2934,10 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
             GccRangeComplexOption != "-fno-cx-fortran-rules")
           EmitComplexRangeDiag(D, GccRangeComplexOption,
                                "-fno-cx-limited-range");
+        // Warn about complex range option overrides incompatible with GCC.
+        if (GccRangeComplexOption == "-fcx-fortran-rules")
+          D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+              << GccRangeComplexOption << A->getSpelling();
       }
       GccRangeComplexOption = "-fno-cx-limited-range";
       LastComplexRangeOption = A->getSpelling();
@@ -3231,6 +3240,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
     case options::OPT_ffast_math:
       applyFastMath(true);
       LastComplexRangeOption = A->getSpelling();
+      // Warn about complex range option overrides incompatible with GCC.
+      if (GccRangeComplexOption == "-fcx-fortran-rules" ||
+          GccRangeComplexOption == "-fno-cx-fortran-rules")
+        D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+            << GccRangeComplexOption << A->getSpelling();
       if (A->getOption().getID() == options::OPT_Ofast)
         LastFpContractOverrideOption = "-Ofast";
       else
@@ -3255,6 +3269,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
           Range != LangOptions::ComplexRangeKind::CX_Full)
         EmitComplexRangeDiag(D, LastComplexRangeOption, "-fno-fast-math");
       Range = LangOptions::ComplexRangeKind::CX_None;
+      // Warn about complex range option overrides incompatible with GCC.
+      if (GccRangeComplexOption == "-fcx-fortran-rules" ||
+          GccRangeComplexOption == "-fcx-limited-range")
+        D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+            << GccRangeComplexOption << A->getSpelling();
       LastComplexRangeOption = "";
       GccRangeComplexOption = "";
       LastFpContractOverrideOption = "";
diff --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c
index 30140f3c208e0..d86bec46589a1 100644
--- a/clang/test/Driver/range.c
+++ b/clang/test/Driver/range.c
@@ -255,6 +255,31 @@
 // RUN: %clang -### -Werror --target=x86_64 -fno-fast-math -ffp-model=strict \
 // RUN:   -c %s 2>&1 | FileCheck --check-prefixes=FULL %s
 
+
+// Test incompatibility of complex range override with GCC 14.2.0.
+
+// RUN: %clang -### --target=x86_64 -fcx-limited-range -fno-fast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT1 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -fcx-limited-range \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT2 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -fno-cx-limited-range \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT3 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -ffast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT4 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -fno-fast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT5 %s
+
+// RUN: %clang -### --target=x86_64 -fno-cx-fortran-rules -fcx-limited-range \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT6 %s
+
+// RUN: %clang -### --target=x86_64 -fno-cx-fortran-rules -ffast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT7 %s
+
+
 // WARN1: warning: overriding '-fcx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option]
 // WARN2: warning: overriding '-fno-cx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option]
 // WARN3: warning: overriding '-fcx-fortran-rules' option with '-fno-cx-limited-range' [-Woverriding-option]
@@ -281,4 +306,12 @@
 // CHECK-NOT: -complex-range=improved
 // RANGE-NOT: -complex-range=
 
+// WARN_INCOMPAT1: warning: combination of '-fcx-limited-range' and '-fno-fast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT2: warning: combination of '-fcx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT3: warning: combination of '-fcx-fortran-rules' and '-fno-cx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT4: warning: combination of '-fcx-fortran-rules' and '-ffast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT5: warning: combination of '-fcx-fortran-rules' and '-fno-fast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT6: warning: combination of '-fno-cx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT7: warning: combination of '-fno-cx-fortran-rules' and '-ffast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+
 // ERR: error: unsupported argument 'foo' to option '-fcomplex-arithmetic='

@llvmbot
Copy link
Member

llvmbot commented Jun 17, 2025

@llvm/pr-subscribers-clang

Author: Shunsuke Watanabe (s-watanabe314)

Changes

This patch adds a warning for incompatible complex number behavior compared to GCC due to Clang's "last-flag-wins" rule.

Incompatibilities with GCC occur in the following seven cases. Clang uses the last specified option, but GCC uses an earlier specified option in these seven cases because it has a different option prioritization.

# Options Complex Division Algorithm in GCC 14.2.0 Complex Division Algorithm in Clang
1 -fcx-limited-range -fno-fast-math algebraic method runtime function call
2 -fcx-fortran-rules -fcx-limited-range Smith's method algebraic method
3 -fcx-fortran-rules -fno-cx-limited-range Smith's method runtime function call
4 -fcx-fortran-rules -ffast-math Smith's method algebraic method
5 -fcx-fortran-rules -fno-fast-math Smith's method runtime function call
6 -fno-cx-fortran-rules -fcx-limited-range runtime function call algebraic method
7 -fno-cx-fortran-rules -ffast-math runtime function call algebraic method

These were discussed at:
https://discourse.llvm.org/t/the-priority-of-fno-fast-math-regarding-complex-number-calculations/84679


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

3 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+19)
  • (modified) clang/test/Driver/range.c (+33)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 20fb47237c56f..377509cfcf2cd 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -520,6 +520,9 @@ def warn_drv_math_errno_enabled_after_veclib: Warning<
   "math errno enabled by '%0' after it was implicitly disabled by '%1',"
   " this may limit the utilization of the vector library">,
   InGroup<MathErrnoEnabledWithVecLib>;
+def warn_drv_gcc_incompatible_complex_range_override: Warning<
+  "combination of '%0' and '%1' results in complex number calculations incompatible with GCC">,
+  InGroup<GccCompat>;
 
 def note_drv_command_failed_diag_msg : Note<
   "diagnostic msg: %0">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1d11be1d82be8..244c4c0848aa6 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2915,6 +2915,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
       } else {
         if (GccRangeComplexOption != "-fno-cx-limited-range")
           EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-limited-range");
+        // Warn about complex range option overrides incompatible with GCC.
+        if (GccRangeComplexOption == "-fcx-fortran-rules" ||
+            GccRangeComplexOption == "-fno-cx-fortran-rules")
+          D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+              << GccRangeComplexOption << A->getSpelling();
       }
       GccRangeComplexOption = "-fcx-limited-range";
       LastComplexRangeOption = A->getSpelling();
@@ -2929,6 +2934,10 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
             GccRangeComplexOption != "-fno-cx-fortran-rules")
           EmitComplexRangeDiag(D, GccRangeComplexOption,
                                "-fno-cx-limited-range");
+        // Warn about complex range option overrides incompatible with GCC.
+        if (GccRangeComplexOption == "-fcx-fortran-rules")
+          D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+              << GccRangeComplexOption << A->getSpelling();
       }
       GccRangeComplexOption = "-fno-cx-limited-range";
       LastComplexRangeOption = A->getSpelling();
@@ -3231,6 +3240,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
     case options::OPT_ffast_math:
       applyFastMath(true);
       LastComplexRangeOption = A->getSpelling();
+      // Warn about complex range option overrides incompatible with GCC.
+      if (GccRangeComplexOption == "-fcx-fortran-rules" ||
+          GccRangeComplexOption == "-fno-cx-fortran-rules")
+        D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+            << GccRangeComplexOption << A->getSpelling();
       if (A->getOption().getID() == options::OPT_Ofast)
         LastFpContractOverrideOption = "-Ofast";
       else
@@ -3255,6 +3269,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
           Range != LangOptions::ComplexRangeKind::CX_Full)
         EmitComplexRangeDiag(D, LastComplexRangeOption, "-fno-fast-math");
       Range = LangOptions::ComplexRangeKind::CX_None;
+      // Warn about complex range option overrides incompatible with GCC.
+      if (GccRangeComplexOption == "-fcx-fortran-rules" ||
+          GccRangeComplexOption == "-fcx-limited-range")
+        D.Diag(clang::diag::warn_drv_gcc_incompatible_complex_range_override)
+            << GccRangeComplexOption << A->getSpelling();
       LastComplexRangeOption = "";
       GccRangeComplexOption = "";
       LastFpContractOverrideOption = "";
diff --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c
index 30140f3c208e0..d86bec46589a1 100644
--- a/clang/test/Driver/range.c
+++ b/clang/test/Driver/range.c
@@ -255,6 +255,31 @@
 // RUN: %clang -### -Werror --target=x86_64 -fno-fast-math -ffp-model=strict \
 // RUN:   -c %s 2>&1 | FileCheck --check-prefixes=FULL %s
 
+
+// Test incompatibility of complex range override with GCC 14.2.0.
+
+// RUN: %clang -### --target=x86_64 -fcx-limited-range -fno-fast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT1 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -fcx-limited-range \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT2 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -fno-cx-limited-range \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT3 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -ffast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT4 %s
+
+// RUN: %clang -### --target=x86_64 -fcx-fortran-rules -fno-fast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT5 %s
+
+// RUN: %clang -### --target=x86_64 -fno-cx-fortran-rules -fcx-limited-range \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT6 %s
+
+// RUN: %clang -### --target=x86_64 -fno-cx-fortran-rules -ffast-math \
+// RUN:   -c %s 2>&1 | FileCheck --check-prefixes=WARN_INCOMPAT7 %s
+
+
 // WARN1: warning: overriding '-fcx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option]
 // WARN2: warning: overriding '-fno-cx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option]
 // WARN3: warning: overriding '-fcx-fortran-rules' option with '-fno-cx-limited-range' [-Woverriding-option]
@@ -281,4 +306,12 @@
 // CHECK-NOT: -complex-range=improved
 // RANGE-NOT: -complex-range=
 
+// WARN_INCOMPAT1: warning: combination of '-fcx-limited-range' and '-fno-fast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT2: warning: combination of '-fcx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT3: warning: combination of '-fcx-fortran-rules' and '-fno-cx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT4: warning: combination of '-fcx-fortran-rules' and '-ffast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT5: warning: combination of '-fcx-fortran-rules' and '-fno-fast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT6: warning: combination of '-fno-cx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+// WARN_INCOMPAT7: warning: combination of '-fno-cx-fortran-rules' and '-ffast-math' results in complex number calculations incompatible with GCC [-Wgcc-compat]
+
 // ERR: error: unsupported argument 'foo' to option '-fcomplex-arithmetic='

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

Thank you for working on this! Please be sure to add a release note to clang/docs/ReleaseNotes.rst so users know about the new diagnostic.

@@ -520,6 +520,9 @@ def warn_drv_math_errno_enabled_after_veclib: Warning<
"math errno enabled by '%0' after it was implicitly disabled by '%1',"
" this may limit the utilization of the vector library">,
InGroup<MathErrnoEnabledWithVecLib>;
def warn_drv_gcc_incompatible_complex_range_override: Warning<
"combination of '%0' and '%1' results in complex number calculations incompatible with GCC">,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we perhaps add note diagnostics or a %select to the warning so we can explain how it's incompatible? I'm worried a user will get this diagnostic and say "okay, great, but... what does that mean and how do I fix that?" and being a bit stuck because they don't know what's incompatible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the feedback! I agree that a user wouldn't know how to handle this warning just by seeing it. How about adding the following note diagnostic and outputting it along with the incompatibility warning?
note: complex multiplication and division use different calculation methods than GCC. specify '%0' after '%1' for GCC compatibility

Implementing this would result in the following output:

$ clang test.cpp -fcx-fortran-rules -fcx-limited-range
clang: warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' [-Woverriding-option]
clang: warning: combination of '-fcx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC [-Wgcc-compat]
clang: note: complex multiplication and division use different calculation methods than GCC. specify '-fcx-fortran-rules' after '-fcx-limited-range' for GCC compatibility

Copy link
Collaborator

Choose a reason for hiding this comment

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

A few thoughts:

  1. It's unfortunate that we emit two warnings for the same thing, especially by default. We really should try to find a way to emit only one warning, I think.
  2. The "different calculation methods" part of the note doesn't really tell the user all that much, but the important part is the "specify '-blah' after '-yada'" bit and that's good to keep.

WDYT?

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 understand that it's better to emit a single warning message. In that case, how about simply adding the "specify" part to the end of the original warning message? At least I think users would understand what to do.
warning: combination of '-fcx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC. specify '-fcx-fortran-rules' after '-fcx-limited-range' for GCC compatibility [-Wgcc-compat]

However, this warning message might be redundant because it's long and displays the same option twice. It might be better to use the following instead:
warning: complex number calculation is incompatible with GCC. specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility [-Wgcc-compat]

Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand that it's better to emit a single warning message. In that case, how about simply adding the "specify" part to the end of the original warning message? At least I think users would understand what to do. warning: combination of '-fcx-fortran-rules' and '-fcx-limited-range' results in complex number calculations incompatible with GCC. specify '-fcx-fortran-rules' after '-fcx-limited-range' for GCC compatibility [-Wgcc-compat]

However, this warning message might be redundant because it's long and displays the same option twice. It might be better to use the following instead: warning: complex number calculation is incompatible with GCC. specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility [-Wgcc-compat]

The logic here might get a bit odd because one warning is -Woverriding-option and the second is -Wgcc-compat. So I think what we want is:

// -Wgcc-compat -Wno-overriding-option
warning: complex number calculation is incompatible with GCC; specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility

// -Woverriding-option -Wno-gcc-compat
warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range'

// -Wgcc-compat -Woverriding-option
warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' and is incompatible with GCC; specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility

though I'm not certain how easy or hard that would be to implement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

// -Wgcc-compat -Wno-overriding-option
warning: complex number calculation is incompatible with GCC; specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility

// -Woverriding-option -Wno-gcc-compat
warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range'

// -Wgcc-compat -Woverriding-option
warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' and is incompatible with GCC; specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility

Does this mean that if we are going to emit both -Woverriding-option and -Wgcc-compat warnings, the warning messages should be combined into one? If there is a way to determine whether the -Woverriding-option option is specified during driver processing (within RenderFloatingPointOptions in Clang.cpp), we might be able to implement this using %select or similar. However, I don't know how to determine if -Woverriding-option is specified.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this mean that if we are going to emit both -Woverriding-option and -Wgcc-compat warnings, the warning messages should be combined into one?

Yeah, I would combine it into one under the -Woverriding-option and use a %select so that the GCC compatibility parts are optionally emitted.

If there is a way to determine whether the -Woverriding-option option is specified during driver processing

IIRC, you can do that by adding an explicit compiler option for it, like:
https://github.com/llvm/llvm-project/blob/31bf9348fa10fc95c4a86ef81485652152bf9906/clang/include/clang/Driver/Options.td#L896C5-L896C17

Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIRC, you can do that by adding an explicit compiler option for it, like:

That method seems implementable. Thank you!

However, I'm concerned that the warning message about the -ffast-math override is being output with an option name that the user didn't specify. For example:

$ clang -fcx-fortran-rules -ffast-math
clang: warning: overriding '-fcx-fortran-rules' option with '-fcomplex-arithmetic=basic' [-Woverriding-option]

$ clang -fno-cx-fortran-rules -ffast-math
clang: warning: overriding '-fno-cx-fortran-rules' option with '-fcomplex-arithmetic=basic' [-Woverriding-option]

If we were to output -Wgcc-compat in conjunction with these, what should the warning message look like? For example, should it output the option name that the user specified, like this?

$ clang -fcx-fortran-rules -ffast-math -Wgcc-compat -Wno-overriding-option
warning: complex number calculation is incompatible with GCC; specify '-ffast-math' after '-fcx-fortran-rules' for compatibility

$ clang -fcx-fortran-rules -ffast-math -Woverriding-option -Wno-gcc-compat
warning: overriding '-fcx-fortran-rules' option with '-ffast-math'

$ clang -fcx-fortran-rules -ffast-math -Wgcc-compat -Woverriding-option
warning: overriding '-fcx-fortran-rules' option with '-ffast-math' and is incompatible with GCC; specify '-ffast-math' after '-fcx-fortran-rules' for compatibility

To achieve this, it might be necessary to first fix the behavior where the override warning messages for -ffast-math and -ffp-model= are output with option names that the user didn't specify.

Copy link
Collaborator

Choose a reason for hiding this comment

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

CC @andykaylor @zahiraam @MaskRay @jansvoboda11 for more input because this is touching on fast math flag diagnostics, the gift which keeps on giving. :-D

I think the current behavior is a bit confusing but is also reasonable. It's letting the user know that the fortran rules are being overridden and what the actual behavior will be, which is nice because the user will at least know what behavior to expect. But the user may not know that the fast math flag is why that happened, so it would be ideal if it said something like overriding '-fcx-fortran-rules' option with '-fcomplex-arithmetic=basic' (implied by '-ffast-math') or something. But I also don't know how hard that would be or what other complexities we may run into.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How about using the warning message that Andy suggested here to display which complex range each option implies? In this case, it might be simpler to implement if we use the same warning message not only for aggregate options (-ffast-math and -ffp-model) but also for GCC options and -fcomplex-arithmetic=. The warnings would look something like this:

$ clang -ffast-math -fcomplex-arithmetic=full
warning: '-fcomplex-arithmtic=full' sets complex range to "full" overriding the setting of "basic" that was implied by '-ffast-math'

$ clang -fcx-fotran-rules -fcx-limited-range
warning: '-fcx-limited-range' sets complex range to "basic" overriding the setting of "improved" that was implied by '-fcx-fortran-rules'

After modifying the overriding warning message as above, and also outputting GCC incompatibility, it might look like this, for example:

$ clang -fcx-fortran-rules -fcx-limited-range -Wno-overriding-option -Wgcc-compat
warning: complex number calculation is incompatible with GCC; specify '-fcx-fortran-rules' after '-fcx-limited-range' for compatibility

$ clang -fcx-fortran-rules -fcx-limited-range -Woverriding-option -Wno-gcc-compat
warning: '-fcx-limited-range' sets complex range to "basic" overriding the setting of "improved" that was implied by '-fcx-fortran-rules'

$ clang -fcx-fortran-rules -fcx-limited-range -Woverriding-option -Wgcc-compat
warning: '-fcx-limited-range' sets complex range to "basic" overriding the setting of "improved" that was implied by '-fcx-fortran-rules' and this is incompatible with GCC; specify '-fcx-fortran-rules' after '-fcx-fortran-rules' for GCC compatibility

I'm a little concerned about the final warning messages becoming long, but what do you think about this implementation? If it seems good, I'll try to implement it.

I'm not a native English speaker, so I would appreciate any suggestions for improving the warning messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants