|
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