Skip to content

Commit 902f1fc

Browse files
[clang][driver] Improve warning message for complex range overrides (llvm#154899)
This patch improves the warnings to show which user options override the complex range. When a complex range is overridden, explicitly display both the option name and the implied complex range value for both the overriding and the overridden options. See also the discussion in the following discourse post: https://discourse.llvm.org/t/the-priority-of-fno-fast-math-regarding-complex-number-calculations/84679
1 parent 79012fc commit 902f1fc

File tree

7 files changed

+692
-168
lines changed

7 files changed

+692
-168
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ def warn_drv_overriding_option : Warning<
485485
def warn_drv_overriding_deployment_version
486486
: Warning<"overriding deployment version from '%0' to '%1'">,
487487
InGroup<DiagGroup<"overriding-deployment-version">>;
488+
def warn_drv_overriding_complex_range : Warning<
489+
"'%1' sets complex range to \"%3\" overriding the setting of \"%2\" that was implied by '%0'">,
490+
InGroup<DiagGroup<"overriding-complex-range">>;
488491
def warn_drv_treating_input_as_cxx : Warning<
489492
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
490493
InGroup<Deprecated>;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 65 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,17 +2730,40 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
27302730
}
27312731
}
27322732

2733-
static std::string ComplexArithmeticStr(LangOptions::ComplexRangeKind Range) {
2734-
return (Range == LangOptions::ComplexRangeKind::CX_None)
2735-
? ""
2736-
: "-fcomplex-arithmetic=" + complexRangeKindToStr(Range);
2737-
}
2733+
static void EmitComplexRangeDiag(const Driver &D, StringRef LastOpt,
2734+
LangOptions::ComplexRangeKind Range,
2735+
StringRef NewOpt,
2736+
LangOptions::ComplexRangeKind NewRange) {
2737+
// Do not emit a warning if NewOpt overrides LastOpt in the following cases.
2738+
//
2739+
// | LastOpt | NewOpt |
2740+
// |-----------------------|-----------------------|
2741+
// | -fcx-limited-range | -fno-cx-limited-range |
2742+
// | -fno-cx-limited-range | -fcx-limited-range |
2743+
// | -fcx-fortran-rules | -fno-cx-fortran-rules |
2744+
// | -fno-cx-fortran-rules | -fcx-fortran-rules |
2745+
// | -ffast-math | -fno-fast-math |
2746+
// | -ffp-model= | -ffast-math |
2747+
// | -ffp-model= | -fno-fast-math |
2748+
// | -ffp-model= | -ffp-model= |
2749+
// | -fcomplex-arithmetic= | -fcomplex-arithmetic= |
2750+
if (LastOpt == NewOpt || NewOpt.empty() || LastOpt.empty() ||
2751+
(LastOpt == "-fcx-limited-range" && NewOpt == "-fno-cx-limited-range") ||
2752+
(LastOpt == "-fno-cx-limited-range" && NewOpt == "-fcx-limited-range") ||
2753+
(LastOpt == "-fcx-fortran-rules" && NewOpt == "-fno-cx-fortran-rules") ||
2754+
(LastOpt == "-fno-cx-fortran-rules" && NewOpt == "-fcx-fortran-rules") ||
2755+
(LastOpt == "-ffast-math" && NewOpt == "-fno-fast-math") ||
2756+
(LastOpt.starts_with("-ffp-model=") && NewOpt == "-ffast-math") ||
2757+
(LastOpt.starts_with("-ffp-model=") && NewOpt == "-fno-fast-math") ||
2758+
(LastOpt.starts_with("-ffp-model=") &&
2759+
NewOpt.starts_with("-ffp-model=")) ||
2760+
(LastOpt.starts_with("-fcomplex-arithmetic=") &&
2761+
NewOpt.starts_with("-fcomplex-arithmetic=")))
2762+
return;
27382763

2739-
static void EmitComplexRangeDiag(const Driver &D, std::string str1,
2740-
std::string str2) {
2741-
if (str1 != str2 && !str2.empty() && !str1.empty()) {
2742-
D.Diag(clang::diag::warn_drv_overriding_option) << str1 << str2;
2743-
}
2764+
D.Diag(clang::diag::warn_drv_overriding_complex_range)
2765+
<< LastOpt << NewOpt << complexRangeKindToStr(Range)
2766+
<< complexRangeKindToStr(NewRange);
27442767
}
27452768

27462769
static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
@@ -2797,31 +2820,29 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
27972820
StringRef BFloat16ExcessPrecision = "";
27982821
LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_None;
27992822
std::string ComplexRangeStr;
2800-
std::string GccRangeComplexOption;
2801-
std::string LastComplexRangeOption;
2802-
2803-
auto setComplexRange = [&](LangOptions::ComplexRangeKind NewRange) {
2804-
// Warn if user expects to perform full implementation of complex
2805-
// multiplication or division in the presence of nnan or ninf flags.
2806-
if (Range != NewRange)
2807-
EmitComplexRangeDiag(D,
2808-
!GccRangeComplexOption.empty()
2809-
? GccRangeComplexOption
2810-
: ComplexArithmeticStr(Range),
2811-
ComplexArithmeticStr(NewRange));
2823+
StringRef LastComplexRangeOption;
2824+
2825+
auto setComplexRange = [&](StringRef NewOption,
2826+
LangOptions::ComplexRangeKind NewRange) {
2827+
// Warn if user overrides the previously set complex number
2828+
// multiplication/division option.
2829+
if (Range != LangOptions::ComplexRangeKind::CX_None && Range != NewRange)
2830+
EmitComplexRangeDiag(D, LastComplexRangeOption, Range, NewOption,
2831+
NewRange);
2832+
LastComplexRangeOption = NewOption;
28122833
Range = NewRange;
28132834
};
28142835

28152836
// Lambda to set fast-math options. This is also used by -ffp-model=fast
2816-
auto applyFastMath = [&](bool Aggressive) {
2837+
auto applyFastMath = [&](bool Aggressive, StringRef CallerOption) {
28172838
if (Aggressive) {
28182839
HonorINFs = false;
28192840
HonorNaNs = false;
2820-
setComplexRange(LangOptions::ComplexRangeKind::CX_Basic);
2841+
setComplexRange(CallerOption, LangOptions::ComplexRangeKind::CX_Basic);
28212842
} else {
28222843
HonorINFs = true;
28232844
HonorNaNs = true;
2824-
setComplexRange(LangOptions::ComplexRangeKind::CX_Promoted);
2845+
setComplexRange(CallerOption, LangOptions::ComplexRangeKind::CX_Promoted);
28252846
}
28262847
MathErrno = false;
28272848
AssociativeMath = true;
@@ -2873,54 +2894,18 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
28732894
default: continue;
28742895

28752896
case options::OPT_fcx_limited_range:
2876-
if (GccRangeComplexOption.empty()) {
2877-
if (Range != LangOptions::ComplexRangeKind::CX_Basic)
2878-
EmitComplexRangeDiag(D, renderComplexRangeOption(Range),
2879-
"-fcx-limited-range");
2880-
} else {
2881-
if (GccRangeComplexOption != "-fno-cx-limited-range")
2882-
EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-limited-range");
2883-
}
2884-
GccRangeComplexOption = "-fcx-limited-range";
2885-
LastComplexRangeOption = A->getSpelling();
2886-
Range = LangOptions::ComplexRangeKind::CX_Basic;
2897+
setComplexRange(A->getSpelling(),
2898+
LangOptions::ComplexRangeKind::CX_Basic);
28872899
break;
28882900
case options::OPT_fno_cx_limited_range:
2889-
if (GccRangeComplexOption.empty()) {
2890-
EmitComplexRangeDiag(D, renderComplexRangeOption(Range),
2891-
"-fno-cx-limited-range");
2892-
} else {
2893-
if (GccRangeComplexOption != "-fcx-limited-range" &&
2894-
GccRangeComplexOption != "-fno-cx-fortran-rules")
2895-
EmitComplexRangeDiag(D, GccRangeComplexOption,
2896-
"-fno-cx-limited-range");
2897-
}
2898-
GccRangeComplexOption = "-fno-cx-limited-range";
2899-
LastComplexRangeOption = A->getSpelling();
2900-
Range = LangOptions::ComplexRangeKind::CX_Full;
2901+
setComplexRange(A->getSpelling(), LangOptions::ComplexRangeKind::CX_Full);
29012902
break;
29022903
case options::OPT_fcx_fortran_rules:
2903-
if (GccRangeComplexOption.empty())
2904-
EmitComplexRangeDiag(D, renderComplexRangeOption(Range),
2905-
"-fcx-fortran-rules");
2906-
else
2907-
EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-fortran-rules");
2908-
GccRangeComplexOption = "-fcx-fortran-rules";
2909-
LastComplexRangeOption = A->getSpelling();
2910-
Range = LangOptions::ComplexRangeKind::CX_Improved;
2904+
setComplexRange(A->getSpelling(),
2905+
LangOptions::ComplexRangeKind::CX_Improved);
29112906
break;
29122907
case options::OPT_fno_cx_fortran_rules:
2913-
if (GccRangeComplexOption.empty()) {
2914-
EmitComplexRangeDiag(D, renderComplexRangeOption(Range),
2915-
"-fno-cx-fortran-rules");
2916-
} else {
2917-
if (GccRangeComplexOption != "-fno-cx-limited-range")
2918-
EmitComplexRangeDiag(D, GccRangeComplexOption,
2919-
"-fno-cx-fortran-rules");
2920-
}
2921-
GccRangeComplexOption = "-fno-cx-fortran-rules";
2922-
LastComplexRangeOption = A->getSpelling();
2923-
Range = LangOptions::ComplexRangeKind::CX_Full;
2908+
setComplexRange(A->getSpelling(), LangOptions::ComplexRangeKind::CX_Full);
29242909
break;
29252910
case options::OPT_fcomplex_arithmetic_EQ: {
29262911
LangOptions::ComplexRangeKind RangeVal;
@@ -2938,25 +2923,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
29382923
<< A->getSpelling() << Val;
29392924
break;
29402925
}
2941-
if (!GccRangeComplexOption.empty()) {
2942-
if (GccRangeComplexOption != "-fcx-limited-range") {
2943-
if (GccRangeComplexOption != "-fcx-fortran-rules") {
2944-
if (RangeVal != LangOptions::ComplexRangeKind::CX_Improved)
2945-
EmitComplexRangeDiag(D, GccRangeComplexOption,
2946-
ComplexArithmeticStr(RangeVal));
2947-
} else {
2948-
EmitComplexRangeDiag(D, GccRangeComplexOption,
2949-
ComplexArithmeticStr(RangeVal));
2950-
}
2951-
} else {
2952-
if (RangeVal != LangOptions::ComplexRangeKind::CX_Basic)
2953-
EmitComplexRangeDiag(D, GccRangeComplexOption,
2954-
ComplexArithmeticStr(RangeVal));
2955-
}
2956-
}
2957-
LastComplexRangeOption =
2958-
Args.MakeArgString(A->getSpelling() + A->getValue());
2959-
Range = RangeVal;
2926+
setComplexRange(Args.MakeArgString(A->getSpelling() + Val), RangeVal);
29602927
break;
29612928
}
29622929
case options::OPT_ffp_model_EQ: {
@@ -2984,19 +2951,20 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
29842951
<< Args.MakeArgString("-ffp-model=" + Val);
29852952
if (Val == "fast") {
29862953
FPModel = Val;
2987-
applyFastMath(false);
2954+
applyFastMath(false, Args.MakeArgString(A->getSpelling() + Val));
29882955
// applyFastMath sets fp-contract="fast"
29892956
LastFpContractOverrideOption = "-ffp-model=fast";
29902957
} else if (Val == "aggressive") {
29912958
FPModel = Val;
2992-
applyFastMath(true);
2959+
applyFastMath(true, Args.MakeArgString(A->getSpelling() + Val));
29932960
// applyFastMath sets fp-contract="fast"
29942961
LastFpContractOverrideOption = "-ffp-model=aggressive";
29952962
} else if (Val == "precise") {
29962963
FPModel = Val;
29972964
FPContract = "on";
29982965
LastFpContractOverrideOption = "-ffp-model=precise";
2999-
setComplexRange(LangOptions::ComplexRangeKind::CX_Full);
2966+
setComplexRange(Args.MakeArgString(A->getSpelling() + Val),
2967+
LangOptions::ComplexRangeKind::CX_Full);
30002968
} else if (Val == "strict") {
30012969
StrictFPModel = true;
30022970
FPExceptionBehavior = "strict";
@@ -3005,11 +2973,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
30052973
LastFpContractOverrideOption = "-ffp-model=strict";
30062974
TrappingMath = true;
30072975
RoundingFPMath = true;
3008-
setComplexRange(LangOptions::ComplexRangeKind::CX_Full);
2976+
setComplexRange(Args.MakeArgString(A->getSpelling() + Val),
2977+
LangOptions::ComplexRangeKind::CX_Full);
30092978
} else
30102979
D.Diag(diag::err_drv_unsupported_option_argument)
30112980
<< A->getSpelling() << Val;
3012-
LastComplexRangeOption = A->getSpelling();
30132981
break;
30142982
}
30152983

@@ -3194,8 +3162,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
31943162
continue;
31953163
[[fallthrough]];
31963164
case options::OPT_ffast_math:
3197-
applyFastMath(true);
3198-
LastComplexRangeOption = A->getSpelling();
3165+
applyFastMath(true, A->getSpelling());
31993166
if (A->getOption().getID() == options::OPT_Ofast)
32003167
LastFpContractOverrideOption = "-Ofast";
32013168
else
@@ -3213,15 +3180,12 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
32133180
ApproxFunc = false;
32143181
SignedZeros = true;
32153182
restoreFPContractState();
3216-
// If the last specified option related to complex range is not
3217-
// -ffast-math or -ffp-model=, emit warning.
3218-
if (LastComplexRangeOption != "-ffast-math" &&
3219-
LastComplexRangeOption != "-ffp-model=" &&
3220-
Range != LangOptions::ComplexRangeKind::CX_Full)
3221-
EmitComplexRangeDiag(D, LastComplexRangeOption, "-fno-fast-math");
3222-
Range = LangOptions::ComplexRangeKind::CX_None;
3183+
if (Range != LangOptions::ComplexRangeKind::CX_Full)
3184+
setComplexRange(A->getSpelling(),
3185+
LangOptions::ComplexRangeKind::CX_None);
3186+
else
3187+
Range = LangOptions::ComplexRangeKind::CX_None;
32233188
LastComplexRangeOption = "";
3224-
GccRangeComplexOption = "";
32253189
LastFpContractOverrideOption = "";
32263190
break;
32273191
} // End switch (A->getOption().getID())

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3516,8 +3516,9 @@ std::string tools::complexRangeKindToStr(LangOptions::ComplexRangeKind Range) {
35163516
case LangOptions::ComplexRangeKind::CX_Promoted:
35173517
return "promoted";
35183518
break;
3519-
default:
3520-
return "";
3519+
case LangOptions::ComplexRangeKind::CX_None:
3520+
return "none";
3521+
break;
35213522
}
35223523
}
35233524

clang/test/Driver/cl-options.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,13 @@
5454
// fpfast: -funsafe-math-optimizations
5555
// fpfast: -ffast-math
5656

57-
// RUN: %clang_cl /fp:fast /fp:precise -### -- %s 2>&1 | FileCheck -check-prefix=fpprecise %s
57+
// RUN: %clang_cl /fp:fast /fp:precise -Wno-overriding-complex-range -### -- %s 2>&1 | \
58+
// RUN: FileCheck -check-prefix=fpprecise %s
5859
// fpprecise-NOT: -funsafe-math-optimizations
5960
// fpprecise-NOT: -ffast-math
6061

61-
// RUN: %clang_cl /fp:fast /fp:strict -### -- %s 2>&1 | FileCheck -check-prefix=fpstrict %s
62+
// RUN: %clang_cl /fp:fast /fp:strict -Wno-overriding-complex-range -### -- %s 2>&1 | \
63+
// RUN: FileCheck -check-prefix=fpstrict %s
6264
// fpstrict-NOT: -funsafe-math-optimizations
6365
// fpstrict-NOT: -ffast-math
6466
// fpstrict: -ffp-contract=off

clang/test/Driver/fp-model.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@
8181
// WARN12: warning: overriding '-ffp-model=strict' option with '-Ofast'
8282

8383
// RUN: %clang -### -ffast-math -ffp-model=strict -c %s 2>&1 | FileCheck \
84-
// RUN: --check-prefix=WARN-CX-BASIC-TO-FULL %s
85-
// WARN-CX-BASIC-TO-FULL: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=full'
84+
// RUN: --check-prefix=CHECK-FASTMATH-FPM-STRICT %s
8685

8786
// RUN: %clang -### -ffp-model=strict -fapprox-func -c %s 2>&1 \
8887
// RUN: | FileCheck --check-prefix=WARN13 %s
@@ -205,7 +204,7 @@
205204

206205
// RUN: %clang -### -nostdinc -ffast-math -ffp-model=fast -c %s 2>&1 \
207206
// RUN: | FileCheck --check-prefix=CHECK-FASTMATH-FPM-FAST %s
208-
// CHECK-FASTMATH-FPM-FAST: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=promoted'
207+
// CHECK-FASTMATH-FPM-FAST: warning: '-ffp-model=fast' sets complex range to "promoted" overriding the setting of "basic" that was implied by '-ffast-math'
209208
// CHECK-FASTMATH-FPM-FAST: "-cc1"
210209
// CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-infs"
211210
// CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-nans"
@@ -221,7 +220,8 @@
221220
// CHECK-FASTMATH-FPM-FAST-SAME: "-complex-range=promoted"
222221

223222
// RUN: %clang -### -nostdinc -ffast-math -ffp-model=precise -c %s 2>&1 \
224-
// RUN: | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-PRECISE,WARN-CX-BASIC-TO-FULL %s
223+
// RUN: | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-PRECISE %s
224+
// CHECK-FASTMATH-FPM-PRECISE: warning: '-ffp-model=precise' sets complex range to "full" overriding the setting of "basic" that was implied by '-ffast-math'
225225
// CHECK-FASTMATH-FPM-PRECISE: "-cc1"
226226
// CHECK-FASTMATH-FPM-PRECISE-NOT: "-menable-no-infs"
227227
// CHECK-FASTMATH-FPM-PRECISE-NOT: "-menable-no-nans"
@@ -237,7 +237,8 @@
237237
// CHECK-FASTMATH-FPM-PRECISE-SAME: "-complex-range=full"
238238

239239
// RUN: %clang -### -nostdinc -ffast-math -ffp-model=strict -c %s 2>&1 \
240-
// RUN: | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-STRICT,WARN-CX-BASIC-TO-FULL %s
240+
// RUN: | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-STRICT %s
241+
// CHECK-FASTMATH-FPM-STRICT: warning: '-ffp-model=strict' sets complex range to "full" overriding the setting of "basic" that was implied by '-ffast-math'
241242
// CHECK-FASTMATH-FPM-STRICT: "-cc1"
242243
// CHECK-FASTMATH-FPM-STRICT-NOT: "-menable-no-infs"
243244
// CHECK-FASTMATH-FPM-STRICT-NOT: "-menable-no-nans"

0 commit comments

Comments
 (0)