Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2997,6 +2997,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_None;
std::string ComplexRangeStr = "";
std::string GccRangeComplexOption = "";
std::string LastComplexRangeOption = "";
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think I remember during our Discourse discussion of this that there was already a GccRangeComplexOption variable here. Do we really need another variable? If you just set GccRangeComplexOption to empty for -ffast-math and -fno-fast-math, would that give us reasonable diagnostics?

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 your feedback!

If you just set GccRangeComplexOption to empty for -ffast-math and -fno-fast-math, would that give us reasonable diagnostics?

I think it's difficult. I believe diagnostics should be emitted when Range specified with options other than -ffast-math is overridden by -fno-fast-math. To distinguish between these cases, I think we need a variable that determines what options, including Clang-specific options, were specified before -fno-fast-math. Even if we empty GccRangeComplexOption when -ffast-math is spcified, it's impossible to distinguish whether the preceding option before -fno-fast-math was -ffast-math or -fcomplex-arithmetic=basic. If it's acceptable to assign "-ffp-model" or "-fcomplex-arithmetic" to GccRangeComplexOption, then a new variable might not be necessary.

Copy link
Member

Choose a reason for hiding this comment

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

std::string LastComplexRangeOption default initialization

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this mean that = "" is unnecessary? I initialized it in the same way as GccRangeComplexOption, but should I remove it?

Copy link
Member

Choose a reason for hiding this comment

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

= "" is unnecessary. The newly introduced variable can drop = "". You can also drop = "" for the two existing variables as this is minor change.


auto setComplexRange = [&](LangOptions::ComplexRangeKind NewRange) {
// Warn if user expects to perform full implementation of complex
Expand All @@ -3015,7 +3016,12 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
if (Aggressive) {
HonorINFs = false;
HonorNaNs = false;
setComplexRange(LangOptions::ComplexRangeKind::CX_Basic);
// If the last specified option related to complex range is
// -fno-fast-math, override 'Range' without warning.
if (LastComplexRangeOption == "-fno-fast-math")
Range = LangOptions::ComplexRangeKind::CX_Basic;
else
setComplexRange(LangOptions::ComplexRangeKind::CX_Basic);
} else {
HonorINFs = true;
HonorNaNs = true;
Expand Down Expand Up @@ -3080,6 +3086,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-limited-range");
}
GccRangeComplexOption = "-fcx-limited-range";
LastComplexRangeOption = "-fcx-limited-range";
Range = LangOptions::ComplexRangeKind::CX_Basic;
break;
case options::OPT_fno_cx_limited_range:
Expand All @@ -3093,6 +3100,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
"-fno-cx-limited-range");
}
GccRangeComplexOption = "-fno-cx-limited-range";
LastComplexRangeOption = "-fno-cx-limited-range";
Range = LangOptions::ComplexRangeKind::CX_Full;
break;
case options::OPT_fcx_fortran_rules:
Expand All @@ -3102,6 +3110,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
else
EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-fortran-rules");
GccRangeComplexOption = "-fcx-fortran-rules";
LastComplexRangeOption = "-fcx-fortran-rules";
Range = LangOptions::ComplexRangeKind::CX_Improved;
break;
case options::OPT_fno_cx_fortran_rules:
Expand All @@ -3114,6 +3123,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
"-fno-cx-fortran-rules");
}
GccRangeComplexOption = "-fno-cx-fortran-rules";
LastComplexRangeOption = "-fno-cx-fortran-rules";
Range = LangOptions::ComplexRangeKind::CX_Full;
break;
case options::OPT_fcomplex_arithmetic_EQ: {
Expand Down Expand Up @@ -3148,6 +3158,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
ComplexArithmeticStr(RangeVal));
}
}
LastComplexRangeOption = "-fcomplex-arithmetic";
Range = RangeVal;
break;
}
Expand Down Expand Up @@ -3201,6 +3212,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
} else
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getSpelling() << Val;
LastComplexRangeOption = "-ffp-model";
break;
}

Expand Down Expand Up @@ -3386,6 +3398,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
[[fallthrough]];
case options::OPT_ffast_math:
applyFastMath(true);
LastComplexRangeOption = "-ffast-math";
if (A->getOption().getID() == options::OPT_Ofast)
LastFpContractOverrideOption = "-Ofast";
else
Expand All @@ -3403,6 +3416,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
ApproxFunc = false;
SignedZeros = true;
restoreFPContractState();
// If the last specified option related to complex range is -ffast-math,
// override 'Range' without warning.
if (LastComplexRangeOption == "-ffast-math")
Range = LangOptions::ComplexRangeKind::CX_Full;
else
setComplexRange(LangOptions::ComplexRangeKind::CX_Full);
LastComplexRangeOption = "-fno-fast-math";
LastFpContractOverrideOption = "";
break;
} // End switch (A->getOption().getID())
Expand Down
61 changes: 53 additions & 8 deletions clang/test/Driver/range.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,45 @@
// RUN: %clang -### -target x86_64 -ffast-math -fcomplex-arithmetic=basic -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=BASIC %s

// BASIC: -complex-range=basic
// FULL: -complex-range=full
// PRMTD: -complex-range=promoted
// BASIC-NOT: -complex-range=improved
// CHECK-NOT: -complex-range=basic
// IMPRVD: -complex-range=improved
// IMPRVD-NOT: -complex-range=basic
// CHECK-NOT: -complex-range=improved
// RUN: %clang -### -target x86_64 -fcx-limited-range -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN21 %s

// RUN: %clang -### -Werror -target x86_64 -fno-cx-limited-range -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL %s

// RUN: %clang -### -target x86_64 -fcx-fortran-rules -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN22 %s

// RUN: %clang -### -Werror -target x86_64 -fno-cx-fortran-rules -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL %s

// RUN: %clang -### -Werror -target x86_64 -ffast-math -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL %s

// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN23 %s

// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=promoted -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN24 %s

// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=improved -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN25 %s

// RUN: %clang -### -Werror -target x86_64 -fcomplex-arithmetic=full -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL %s

// RUN: %clang -### -target x86_64 -ffp-model=aggressive -fno-fast-math \
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this should result in a warning, and if it does the fact that the warning is about complex is likely to confuse some users. The test is checking for this:

warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=full' [-Woverriding-option]

But neither of those options was explicitly used.

// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN23 %s

// RUN: %clang -### -target x86_64 -ffp-model=fast -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL,WARN24 %s
Copy link
Contributor

Choose a reason for hiding this comment

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

As above, I don't think there should be a warning here.


// RUN: %clang -### -Werror -target x86_64 -ffp-model=precise -fno-fast-math \
// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL %s

// RUN: %clang -### -Werror -target x86_64 -ffp-model=strict -fno-fast-math \
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add test cases for when -fno-fast-math is followed by other options that change the complex mode?

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 added test cases.

// RUN: -c %s 2>&1 | FileCheck --check-prefixes=FULL %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]
Expand All @@ -196,5 +227,19 @@
// WARN14: overriding '-complex-range=promoted' option with '-fcx-limited-range' [-Woverriding-option]
// WARN17: warning: overriding '-fcomplex-arithmetic=full' option with '-fcomplex-arithmetic=basic' [-Woverriding-option]
// WARN20: warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' [-Woverriding-option]
// WARN21: warning: overriding '-fcx-limited-range' option with '-fcomplex-arithmetic=full' [-Woverriding-option]
// WARN22: warning: overriding '-fcx-fortran-rules' option with '-fcomplex-arithmetic=full' [-Woverriding-option]
// WARN23: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=full' [-Woverriding-option]
// WARN24: warning: overriding '-fcomplex-arithmetic=promoted' option with '-fcomplex-arithmetic=full' [-Woverriding-option]
// WARN25: warning: overriding '-fcomplex-arithmetic=improved' option with '-fcomplex-arithmetic=full' [-Woverriding-option]

// BASIC: -complex-range=basic
// FULL: -complex-range=full
// PRMTD: -complex-range=promoted
// BASIC-NOT: -complex-range=improved
// CHECK-NOT: -complex-range=basic
// IMPRVD: -complex-range=improved
// IMPRVD-NOT: -complex-range=basic
// CHECK-NOT: -complex-range=improved

// ERR: error: unsupported argument 'foo' to option '-fcomplex-arithmetic='