|
41 | 41 | #include "clang/Driver/SanitizerArgs.h"
|
42 | 42 | #include "clang/Driver/Types.h"
|
43 | 43 | #include "clang/Driver/XRayArgs.h"
|
| 44 | +#include "llvm/ADT/ScopeExit.h" |
44 | 45 | #include "llvm/ADT/SmallSet.h"
|
45 | 46 | #include "llvm/ADT/StringExtras.h"
|
46 | 47 | #include "llvm/BinaryFormat/Magic.h"
|
@@ -2857,6 +2858,10 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
|
2857 | 2858 | // List of veclibs which when used with -fveclib imply -fno-math-errno.
|
2858 | 2859 | constexpr std::array VecLibImpliesNoMathErrno{llvm::StringLiteral("ArmPL"),
|
2859 | 2860 | llvm::StringLiteral("SLEEF")};
|
| 2861 | + bool NoMathErrnoWasImpliedByVecLib = false; |
| 2862 | + const Arg *VecLibArg = nullptr; |
| 2863 | + // Track the arg (if any) that reenabled errno after -fveclib for diagnostics. |
| 2864 | + const Arg *ArgThatReenabledMathErrnoAfterVecLib = nullptr; |
2860 | 2865 |
|
2861 | 2866 | // Handle various floating point optimization flags, mapping them to the
|
2862 | 2867 | // appropriate LLVM code generation flags. This is complicated by several
|
@@ -2964,6 +2969,12 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
|
2964 | 2969 | }
|
2965 | 2970 |
|
2966 | 2971 | for (const Arg *A : Args) {
|
| 2972 | + auto CheckMathErrnoForVecLib = |
| 2973 | + llvm::make_scope_exit([&, MathErrnoBeforeArg = MathErrno] { |
| 2974 | + if (NoMathErrnoWasImpliedByVecLib && !MathErrnoBeforeArg && MathErrno) |
| 2975 | + ArgThatReenabledMathErrnoAfterVecLib = A; |
| 2976 | + }); |
| 2977 | + |
2967 | 2978 | switch (A->getOption().getID()) {
|
2968 | 2979 | // If this isn't an FP option skip the claim below
|
2969 | 2980 | default: continue;
|
@@ -3130,8 +3141,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
|
3130 | 3141 | FPExceptionBehavior = "strict";
|
3131 | 3142 | break;
|
3132 | 3143 | case options::OPT_fveclib:
|
3133 |
| - if (llvm::is_contained(VecLibImpliesNoMathErrno, A->getValue())) |
| 3144 | + VecLibArg = A; |
| 3145 | + if (llvm::is_contained(VecLibImpliesNoMathErrno, A->getValue())) { |
3134 | 3146 | MathErrno = false;
|
| 3147 | + NoMathErrnoWasImpliedByVecLib = true; |
| 3148 | + } |
3135 | 3149 | break;
|
3136 | 3150 | case options::OPT_fno_trapping_math:
|
3137 | 3151 | if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
|
@@ -3346,8 +3360,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
|
3346 | 3360 | if (ApproxFunc)
|
3347 | 3361 | CmdArgs.push_back("-fapprox-func");
|
3348 | 3362 |
|
3349 |
| - if (MathErrno) |
| 3363 | + if (MathErrno) { |
3350 | 3364 | CmdArgs.push_back("-fmath-errno");
|
| 3365 | + if (NoMathErrnoWasImpliedByVecLib) |
| 3366 | + D.Diag(clang::diag::warn_drv_math_errno_reenabled_after_veclib) |
| 3367 | + << ArgThatReenabledMathErrnoAfterVecLib->getAsString(Args) |
| 3368 | + << VecLibArg->getAsString(Args); |
| 3369 | + } |
3351 | 3370 |
|
3352 | 3371 | if (AssociativeMath && ReciprocalMath && !SignedZeros && ApproxFunc &&
|
3353 | 3372 | !TrappingMath)
|
|
0 commit comments