[clang] Add clang warning if fp exception functions are called without appropriate flags/pragmas (#128239) (PR #187860)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 21 05:32:33 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Marcos Ramirez Joos (maarcosrmz)
<details>
<summary>Changes</summary>
This pull request relates to issue (#<!-- -->128239).
In the first commit, warnings were only added for 5 out of the 11 functions (see [this](https://linux.die.net/man/3/fetestexcept)):
* `int feclearexcept(int excepts);`
* `int feraiseexcept(int excepts);`
* `int fetestexcept(int excepts);`
* `int fegetround(void);`
* `int fesetround(int rounding_mode);`
The changes were tested locally both with and without `#pragma STDC FENV_ACCESS ON` as well as compiling with and without the compiler flag '-ffp-exception-behavior=maytrap', resulting in the expected behaviour described by the issue. Sample output (pragma/flag not set):
```sh
$ ./build/bin/clang test.c -lm
test.c:8:3: warning: 'feclearexcept' used without enabling floating-point exception behavior; use 'pragma STDCFENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'
[-Wfenv-access]
8 | feclearexcept(FE_INVALID);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
test.c:10:3: warning: 'feraiseexcept' used without enabling floating-point exception behavior; use 'pragma STDCFENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'
[-Wfenv-access]
10 | feraiseexcept(FE_INVALID);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
test.c:12:3: warning: 'fetestexcept' used without enabling floating-point exception behavior; use 'pragma STDCFENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'
[-Wfenv-access]
12 | fetestexcept(FE_INVALID);
| ^~~~~~~~~~~~~~~~~~~~~~~~
test.c:13:11: warning: 'fegetround' used without enabling floating-point exception behavior; use 'pragma STDCFENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'
[-Wfenv-access]
13 | int i = fegetround();
| ^~~~~~~~~~~~
test.c:15:3: warning: 'fesetround' used without enabling floating-point exception behavior; use 'pragma STDCFENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'
[-Wfenv-access]
15 | fesetround(0);
| ^~~~~~~~~~~~~
5 warnings generated.
```
**Note**: Support for the remaining 6 functions was not added due to their prototypes including non-basic types, e.g. `fenv_t`. Adding these functions to `clang/include/clang/Basic/Builtins.td` results in errors like:
```sh
$ cmake --build build
[1/1045] Building Builtins.inc...
FAILED: [code=1] tools/clang/include/clang/Basic/Builtins.inc /home/<user>/dev/oss/llvm/llvm-project/build/tools/clang/include/clang/Basic/Builtins.inc
cd /home/<user>/dev/oss/llvm/llvm-project/build/tools/clang/include/clang/Basic && /home/<user>/dev/oss/llvm/llvm-project/build/bin/clang-tblgen -gen-clang-builtins -I/home/<user>/dev/oss/llvm/llvm-project/clang/include/clang/Basic -I/home/<user>/dev/oss/llvm/llvm-project/clang/include -I/home/<user>/dev/oss/llvm/llvm-project/build/tools/clang/include -I/home/<user>/dev/oss/llvm/llvm-project/build/include -I/home/<user>/dev/oss/llvm/llvm-project/llvm/include /home/<user>/dev/oss/llvm/llvm-project/clang/include/clang/Basic/Builtins.td --write-if-changed -o Builtins.inc -d Builtins.inc.d && /usr/bin/cmake -E cmake_transform_depfile Ninja gccdepfile /home/<user>/dev/oss/llvm/llvm-project/llvm /home/<user>/dev/oss/llvm/llvm-project/clang/include/clang/Basic /home/<user>/dev/oss/llvm/llvm-project/build /home/<user>/dev/oss/llvm/llvm-project/build/tools/clang/include/clang/Basic /home/<user>/dev/oss/llvm/llvm-project/build/tools/clang/include/clang/Basic/Builtins.inc.d /home/<user>/dev/oss/llvm/llvm-project/build/CMakeFiles/d/782b9558ba052deea0a4e2652d46d9bd336ed7b27f8cd46fb2ef5ed62ca0bdca.d
/home/<user>/dev/oss/llvm/llvm-project/clang/include/clang/Basic/Builtins.td:4439:7: error: Unknown Type: fenv_t
let Prototype = "int(fenv_t*)";
^
[2/1045] Generating VCSRevision.h
ninja: build stopped: subcommand failed.
```
With some additional guidance helping me to make this work, I would be happy to add the warning for the remaining functions.
---
Full diff: https://github.com/llvm/llvm-project/pull/187860.diff
4 Files Affected:
- (modified) clang/include/clang/Basic/BuiltinHeaders.def (+1)
- (modified) clang/include/clang/Basic/Builtins.td (+25)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+5)
- (modified) clang/lib/Sema/SemaChecking.cpp (+11)
``````````diff
diff --git a/clang/include/clang/Basic/BuiltinHeaders.def b/clang/include/clang/Basic/BuiltinHeaders.def
index d6012a896eca9..a999d3f715636 100644
--- a/clang/include/clang/Basic/BuiltinHeaders.def
+++ b/clang/include/clang/Basic/BuiltinHeaders.def
@@ -17,6 +17,7 @@ HEADER(BLOCKS_H, "Blocks.h")
HEADER(COMPLEX_H, "complex.h")
HEADER(CTYPE_H, "ctype.h")
HEADER(EMMINTRIN_H, "emmintrin.h")
+HEADER(FENV_H, "fenv.h")
HEADER(FOUNDATION_NSOBJCRUNTIME_H, "Foundation/NSObjCRuntime.h")
HEADER(IMMINTRIN_H, "immintrin.h")
HEADER(INTRIN_H, "intrin.h")
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 8e002c5b900aa..862dfd5d37049 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4409,6 +4409,31 @@ def BlockObjectDispose : LibBuiltin<"blocks.h"> {
}
// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
+def FeClearExcept : LibBuiltin<"fenv.h"> {
+ let Spellings = ["feclearexcept"];
+ let Prototype = "int(int)";
+}
+
+def FeRaiseExcept : LibBuiltin<"fenv.h"> {
+ let Spellings = ["feraiseexcept"];
+ let Prototype = "int(int)";
+}
+
+def FeTestExcept : LibBuiltin<"fenv.h"> {
+ let Spellings = ["fetestexcept"];
+ let Prototype = "int(int)";
+}
+
+def FeGetRound : LibBuiltin<"fenv.h"> {
+ let Spellings = ["fegetround"];
+ let Prototype = "int()";
+}
+
+def FeSetRound : LibBuiltin<"fenv.h"> {
+ let Spellings = ["fesetround"];
+ let Prototype = "int(int)";
+}
+
def __Addressof : LangBuiltin<"CXX_LANG"> {
let Spellings = ["__addressof"];
let Attributes = [FunctionWithoutBuiltinPrefix, NoThrow, Const,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d4d09a8ecef36..6a4f139662e31 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1032,6 +1032,11 @@ def err_ptrauth_indirect_goto_addrlabel_arithmetic : Error<
"%select{subtraction|addition}0 of address-of-label expressions is not "
"supported with ptrauth indirect gotos">;
+def warn_fe_access_without_fenv_access : Warning<
+ "'%0' used without enabling floating-point exception behavior; use 'pragma STDC"
+ "FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'">,
+ InGroup<DiagGroup<"fenv-access">>;
+
// __ptrauth qualifier
def err_ptrauth_qualifier_invalid : Error<
"%select{return type|parameter type|property}1 may not be qualified with "
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 29add9d092e6b..516731ff0ca3d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3845,6 +3845,17 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (BuiltinCountedByRef(TheCall))
return ExprError();
break;
+
+ case Builtin::BIfeclearexcept:
+ case Builtin::BIferaiseexcept:
+ case Builtin::BIfetestexcept:
+ case Builtin::BIfegetround:
+ case Builtin::BIfesetround:
+ if (!TheCall->getFPFeaturesInEffect(getLangOpts()).getAllowFEnvAccess() &&
+ getLangOpts().getFPExceptionMode() != LangOptions::FPE_MayTrap) {
+ Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access)
+ << FDecl->getName() << TheCall->getSourceRange();
+ }
}
if (getLangOpts().HLSL && HLSL().CheckBuiltinFunctionCall(BuiltinID, TheCall))
``````````
</details>
https://github.com/llvm/llvm-project/pull/187860
More information about the cfe-commits
mailing list