https://github.com/maarcosrmz updated 
https://github.com/llvm/llvm-project/pull/199009

>From 8aa17c041db51962fecb13aab05aa47258591fc8 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:18 +0200
Subject: [PATCH 01/17] Added warning for feclearexcept, feraiseexcept,
 fetestexcept, fegetround, and fesetround being used without appropriate
 flags/pragmas (#128239)

---
 clang/include/clang/Basic/BuiltinHeaders.def  |  1 +
 clang/include/clang/Basic/Builtins.td         | 25 +++++++++++++++++++
 .../clang/Basic/DiagnosticSemaKinds.td        |  5 ++++
 clang/lib/Sema/SemaChecking.cpp               | 11 ++++++++
 4 files changed, 42 insertions(+)

diff --git a/clang/include/clang/Basic/BuiltinHeaders.def 
b/clang/include/clang/Basic/BuiltinHeaders.def
index 23889a22769ed..f77665a2e8975 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 40ec94ab75046..b0ca7b5c641d1 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4599,6 +4599,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 142f848f37e50..9b1ccd8ef065b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1041,6 +1041,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 cc834bbee23c4..9c2e4f89ca14c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3928,6 +3928,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()).getExceptionMode() ==
+        LangOptions::FPE_Ignore) {
+      Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access)
+          << FDecl->getName() << TheCall->getSourceRange();
+    }
   }
 
   if (getLangOpts().HLSL && HLSL().CheckBuiltinFunctionCall(BuiltinID, 
TheCall))

>From c5f16d8e61d12ef385fd787edda8dbe3aacd946a Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:18 +0200
Subject: [PATCH 02/17] Added regression tests for fenv access warning

---
 clang/test/Sema/fenv-access.c | 37 +++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 clang/test/Sema/fenv-access.c

diff --git a/clang/test/Sema/fenv-access.c b/clang/test/Sema/fenv-access.c
new file mode 100644
index 0000000000000..57d4debfa9c73
--- /dev/null
+++ b/clang/test/Sema/fenv-access.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -verify -Wfenv-access %s
+// RUN: %clang_cc1 -verify -Wfenv-access -ffp-exception-behavior=maytrap 
-DNO_WARN %s
+// RUN: %clang_cc1 -verify -Wfenv-access -ffp-exception-behavior=strict 
-DNO_WARN %s
+
+int feclearexcept(int excepts);
+int feraiseexcept(int excepts);
+int fetestexcept(int excepts);
+int fegetround(void);
+int fesetround(int rounding_mode);
+
+#define FE_INVALID 1
+
+void test_fenv_access_off(void) {
+#ifdef NO_WARN
+  // expected-no-diagnostics
+  feclearexcept(FE_INVALID);
+  feraiseexcept(FE_INVALID);
+  fetestexcept(FE_INVALID);
+  fegetround();
+  fesetround(0);
+#else 
+  feclearexcept(FE_INVALID); // expected-warning {{'feclearexcept' used 
without enabling floating-point exception behavior; use 'pragma STDC 
FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'}}
+  feraiseexcept(FE_INVALID); // expected-warning {{'feraiseexcept' used 
without enabling floating-point exception behavior; use 'pragma STDC 
FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'}}
+  fetestexcept(FE_INVALID); // expected-warning {{'fetestexcept' used without 
enabling floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or 
compile with '-ffp-exception-behavior=maytrap'}}
+  fegetround(); // expected-warning {{'fegetround' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
+  fesetround(0); // expected-warning {{'fesetround' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
+#endif
+}
+
+void test_fenv_access_on(void) {
+  #pragma STDC FENV_ACCESS ON
+  feclearexcept(FE_INVALID);
+  feraiseexcept(FE_INVALID);
+  fetestexcept(FE_INVALID);
+  fegetround();
+  fesetround(0);
+}

>From 891bc5f10eb3894691e4f4916319bf2dbf947e01 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:19 +0200
Subject: [PATCH 03/17] Added builtin types fexcept_t and fenv_t (fenv.h)

---
 clang/include/clang/AST/ASTContext.h          | 35 +++++++++++++++++-
 clang/include/clang/Basic/TokenKinds.def      |  2 ++
 .../include/clang/Serialization/ASTBitCodes.h |  8 ++++-
 clang/lib/AST/ASTContext.cpp                  | 19 ++++++++++
 clang/lib/Sema/SemaDecl.cpp                   |  8 +++++
 clang/lib/Serialization/ASTReader.cpp         | 36 +++++++++++++++++++
 clang/lib/Serialization/ASTWriter.cpp         |  2 ++
 clang/utils/TableGen/ClangBuiltinsEmitter.cpp |  2 ++
 8 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index b2fd522e6865c..d0a402e59ff60 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -498,6 +498,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// The type for the C ucontext_t type.
   TypeDecl *ucontext_tDecl = nullptr;
 
+  /// The type for the C fexcept_t type.
+  TypeDecl *fexcept_tDecl = nullptr;
+
+  /// The type for the C fenv_t type.
+  TypeDecl *fenv_tDecl = nullptr;
+
   /// Type for the Block descriptor for Blocks CodeGen.
   ///
   /// Since this is only used for generation of debug info, it is not
@@ -2350,6 +2356,30 @@ class ASTContext : public RefCountedBase<ASTContext> {
     return QualType();
   }
 
+  /// Set the type for the C fexcept_t type.
+  void setfexcept_tDecl(TypeDecl *fexcept_tDecl) {
+    this->fexcept_tDecl = fexcept_tDecl;
+  }
+
+  /// Retrieve the C fexcept_t type.
+  QualType getfexcept_tType() const {
+    if (fexcept_tDecl)
+      return getTypeDeclType(ElaboratedTypeKeyword::None,
+                             /*Qualifier=*/std::nullopt, fexcept_tDecl);
+    return QualType();
+  }
+
+  /// Set the type for the C fenv_t type.
+  void setfenv_tDecl(TypeDecl *fenv_tDecl) { this->fenv_tDecl = fenv_tDecl; }
+
+  /// Retrieve the C fenv_t type.
+  QualType getfenv_tType() const {
+    if (fenv_tDecl)
+      return getTypeDeclType(ElaboratedTypeKeyword::None,
+                             /*Qualifier=*/std::nullopt, fenv_tDecl);
+    return QualType();
+  }
+
   /// The result type of logical operations, '<', '>', '!=', etc.
   CanQualType getLogicalOperationType() const {
     return getLangOpts().CPlusPlus ? BoolTy : IntTy;
@@ -2630,7 +2660,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
     GE_Missing_setjmp,
 
     /// Missing a type from <ucontext.h>
-    GE_Missing_ucontext
+    GE_Missing_ucontext,
+
+    /// Missing a type from <fenv.h>
+    GE_Missing_fenv
   };
 
   QualType DecodeTypeStr(const char *&Str, const ASTContext &Context,
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index f07d8ebb75035..4bd21b4112580 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -877,6 +877,8 @@ NOTABLE_IDENTIFIER(FILE)
 NOTABLE_IDENTIFIER(jmp_buf)
 NOTABLE_IDENTIFIER(sigjmp_buf)
 NOTABLE_IDENTIFIER(ucontext_t)
+NOTABLE_IDENTIFIER(fexcept_t)
+NOTABLE_IDENTIFIER(fenv_t)
 NOTABLE_IDENTIFIER(float_t)
 NOTABLE_IDENTIFIER(double_t)
 
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index 3c8f3ba59a07e..4bb287af687b5 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1225,7 +1225,13 @@ enum SpecialTypeIDs {
   SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6,
 
   /// C ucontext_t typedef type
-  SPECIAL_TYPE_UCONTEXT_T = 7
+  SPECIAL_TYPE_UCONTEXT_T = 7,
+
+  /// C fexcept_t typedef type
+  SPECIAL_TYPE_FEXCEPT_T = 8,
+
+  /// C fenv_t typedef type
+  SPECIAL_TYPE_FENV_T = 9
 };
 
 /// The number of special type IDs.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bc4771aec77d1..412ba583353d2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12849,6 +12849,25 @@ static QualType DecodeTypeFromStr(const char *&Str, 
const ASTContext &Context,
   case 'm':
     Type = Context.MFloat8Ty;
     break;
+  case 'T':
+    switch (*Str++) {
+    case 'x': {
+      Type = Context.getfexcept_tType();
+      break;
+    }
+    case 'e': {
+      Type = Context.getfenv_tType();
+      break;
+    }
+    default: {
+      llvm_unreachable("Unexpected target builtin type");
+    }
+    }
+    if (Type.isNull()) {
+      Error = ASTContext::GE_Missing_fenv;
+      return {};
+    }
+    break;
   }
 
   // If there are modifiers and if we're allowed to parse them, go for it.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 62cb9360d1322..30c671269cd00 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2398,6 +2398,8 @@ static StringRef getHeaderName(Builtin::Context 
&BuiltinInfo, unsigned ID,
     return "setjmp.h";
   case ASTContext::GE_Missing_ucontext:
     return "ucontext.h";
+  case ASTContext::GE_Missing_fenv:
+    return "fenv.h";
   }
   llvm_unreachable("unhandled error kind");
 }
@@ -7020,6 +7022,12 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, 
TypedefNameDecl *NewTD,
       case tok::NotableIdentifierKind::ucontext_t:
         Context.setucontext_tDecl(NewTD);
         break;
+      case tok::NotableIdentifierKind::fexcept_t:
+        Context.setfexcept_tDecl(NewTD);
+        break;
+      case tok::NotableIdentifierKind::fenv_t:
+        Context.setfenv_tDecl(NewTD);
+        break;
       case tok::NotableIdentifierKind::float_t:
       case tok::NotableIdentifierKind::double_t:
         NewTD->addAttr(AvailableOnlyInDefaultEvalMethodAttr::Create(Context));
diff --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 06bc8f8c8c13e..f13b70d695b0d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5755,6 +5755,42 @@ void ASTReader::InitializeContext() {
         }
       }
     }
+
+    if (TypeID Fexcept_t = SpecialTypes[SPECIAL_TYPE_FEXCEPT_T]) {
+      QualType Fexcept_tType = GetType(Fexcept_t);
+      if (Fexcept_tType.isNull()) {
+        Error("fexcept_t type is NULL");
+        return;
+      }
+
+      if (!Context.fexcept_tDecl) {
+        if (const TypedefType *Typedef = Fexcept_tType->getAs<TypedefType>())
+          Context.setfexcept_tDecl(Typedef->getDecl());
+        else {
+          const TagType *Tag = Fexcept_tType->getAs<TagType>();
+          assert(Tag && "Invalid fexcept_t type in AST file");
+          Context.setfexcept_tDecl(Tag->getDecl());
+        }
+      }
+    }
+
+    if (TypeID Fenv_t = SpecialTypes[SPECIAL_TYPE_FENV_T]) {
+      QualType Fenv_tType = GetType(Fenv_t);
+      if (Fenv_tType.isNull()) {
+        Error("fenv_t type is NULL");
+        return;
+      }
+
+      if (!Context.fenv_tDecl) {
+        if (const TypedefType *Typedef = Fenv_tType->getAs<TypedefType>())
+          Context.setfenv_tDecl(Typedef->getDecl());
+        else {
+          const TagType *Tag = Fenv_tType->getAs<TagType>();
+          assert(Tag && "Invalid fenv_t type in AST file");
+          Context.setfenv_tDecl(Tag->getDecl());
+        }
+      }
+    }
   }
 
   ReadPragmaDiagnosticMappings(Context.getDiagnostics());
diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 074b0fccdb65d..9dbbdc0249caf 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6159,6 +6159,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, 
StringRef isysroot,
     AddTypeRef(Context, Context.ObjCClassRedefinitionType, SpecialTypes);
     AddTypeRef(Context, Context.ObjCSelRedefinitionType, SpecialTypes);
     AddTypeRef(Context, Context.getucontext_tType(), SpecialTypes);
+    AddTypeRef(Context, Context.getfexcept_tType(), SpecialTypes);
+    AddTypeRef(Context, Context.getfenv_tType(), SpecialTypes);
   }
 
   if (SemaPtr)
diff --git a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp 
b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
index c2e38c0d6aeb8..2394c3b299c81 100644
--- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
@@ -376,6 +376,8 @@ class PrototypeParser {
                                .Case("uint64_t", "UWi")
                                .Case("void", "v")
                                .Case("wchar_t", "w")
+                               .Case("fexcept_t", "Tx")
+                               .Case("fenv_t", "Te")
                                .Case("...", ".")
                                .Default("error");
       if (ReturnTypeVal == "error")

>From e1b5360d879a7adfae4c794820779c7667fc02ce Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:20 +0200
Subject: [PATCH 04/17] Added warning for fegetexceptflag, fesetexceptflag,
 fegetenv, feholdexcept, fesetenv, feupdateenv being used without appropriate
 flags/pragmas (#128239)

---
 clang/include/clang/Basic/Builtins.td | 30 +++++++++++++++++++++++++++
 clang/lib/Sema/SemaChecking.cpp       |  6 ++++++
 2 files changed, 36 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index b0ca7b5c641d1..7b833487e23a2 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4604,11 +4604,21 @@ def FeClearExcept : LibBuiltin<"fenv.h"> {
   let Prototype = "int(int)";
 }
 
+def FeGetExceptFlag : LibBuiltin<"fenv.h"> {
+  let Spellings = ["fegetexceptflag"];
+  let Prototype = "int(fexcept_t*, int)";
+}
+
 def FeRaiseExcept : LibBuiltin<"fenv.h"> {
   let Spellings = ["feraiseexcept"];
   let Prototype = "int(int)";
 }
 
+def FeSetExceptFlag : LibBuiltin<"fenv.h"> {
+  let Spellings = ["fesetexceptflag"];
+  let Prototype = "int(fexcept_t const*, int)";
+}
+
 def FeTestExcept : LibBuiltin<"fenv.h"> {
   let Spellings = ["fetestexcept"];
   let Prototype = "int(int)";
@@ -4624,6 +4634,26 @@ def FeSetRound : LibBuiltin<"fenv.h"> {
   let Prototype = "int(int)";
 }
 
+def FeGetEnv : LibBuiltin<"fenv.h"> {
+  let Spellings = ["fegetenv"];
+  let Prototype = "int(fenv_t*)";
+}
+
+def FeHoldExcept : LibBuiltin<"fenv.h"> {
+  let Spellings = ["feholdexcept"];
+  let Prototype = "int(fenv_t*)";
+}
+
+def FeSetEnv : LibBuiltin<"fenv.h"> {
+  let Spellings = ["fesetenv"];
+  let Prototype = "int(fenv_t const*)";
+}
+
+def FeUpdateEnv : LibBuiltin<"fenv.h"> {
+  let Spellings = ["feupdateenv"];
+  let Prototype = "int(fenv_t const*)";
+}
+
 def __Addressof : LangBuiltin<"CXX_LANG"> {
   let Spellings = ["__addressof"];
   let Attributes = [FunctionWithoutBuiltinPrefix, NoThrow, Const,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9c2e4f89ca14c..8c4c51f403e93 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3930,10 +3930,16 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
     break;
 
   case Builtin::BIfeclearexcept:
+  case Builtin::BIfegetexceptflag:
   case Builtin::BIferaiseexcept:
+  case Builtin::BIfesetexceptflag:
   case Builtin::BIfetestexcept:
   case Builtin::BIfegetround:
   case Builtin::BIfesetround:
+  case Builtin::BIfegetenv:
+  case Builtin::BIfeholdexcept:
+  case Builtin::BIfesetenv:
+  case Builtin::BIfeupdateenv:
     if (TheCall->getFPFeaturesInEffect(getLangOpts()).getExceptionMode() ==
         LangOptions::FPE_Ignore) {
       Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access)

>From 85b850e75ba9411716a1504cfe36fde36c4eb6ad Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:20 +0200
Subject: [PATCH 05/17] Added additional regression tests for fenv access
 warning

---
 clang/test/Sema/fenv-access.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/clang/test/Sema/fenv-access.c b/clang/test/Sema/fenv-access.c
index 57d4debfa9c73..3a7b95af7ab4c 100644
--- a/clang/test/Sema/fenv-access.c
+++ b/clang/test/Sema/fenv-access.c
@@ -2,36 +2,67 @@
 // RUN: %clang_cc1 -verify -Wfenv-access -ffp-exception-behavior=maytrap 
-DNO_WARN %s
 // RUN: %clang_cc1 -verify -Wfenv-access -ffp-exception-behavior=strict 
-DNO_WARN %s
 
+typedef struct {} fenv_t;
+typedef unsigned short int fexcept_t;
+
 int feclearexcept(int excepts);
+int fegetexceptflag(fexcept_t *flagp, int excepts);
 int feraiseexcept(int excepts);
+int fesetexceptflag(const fexcept_t *flagp, int excepts);
 int fetestexcept(int excepts);
 int fegetround(void);
 int fesetround(int rounding_mode);
+int fegetenv(fenv_t *envp);
+int feholdexcept(fenv_t *envp);
+int fesetenv(const fenv_t *envp);
+int feupdateenv(const fenv_t *envp);
 
 #define FE_INVALID 1
 
+fexcept_t *flagp = 0;
+fenv_t *envp = 0;
+
 void test_fenv_access_off(void) {
 #ifdef NO_WARN
   // expected-no-diagnostics
   feclearexcept(FE_INVALID);
+  fegetexceptflag(flagp, FE_INVALID);
   feraiseexcept(FE_INVALID);
+  fesetexceptflag(flagp, FE_INVALID);
   fetestexcept(FE_INVALID);
   fegetround();
   fesetround(0);
+  fegetenv(envp);
+  feholdexcept(envp);
+  fesetenv(envp);
+  feupdateenv(envp);
 #else 
   feclearexcept(FE_INVALID); // expected-warning {{'feclearexcept' used 
without enabling floating-point exception behavior; use 'pragma STDC 
FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'}}
+  fegetexceptflag(flagp, FE_INVALID); // expected-warning {{'fegetexceptflag' 
used without enabling floating-point exception behavior; use 'pragma STDC 
FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'}}
   feraiseexcept(FE_INVALID); // expected-warning {{'feraiseexcept' used 
without enabling floating-point exception behavior; use 'pragma STDC 
FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'}}
+  fesetexceptflag(flagp, FE_INVALID); // expected-warning {{'fesetexceptflag' 
used without enabling floating-point exception behavior; use 'pragma STDC 
FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'}}
   fetestexcept(FE_INVALID); // expected-warning {{'fetestexcept' used without 
enabling floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or 
compile with '-ffp-exception-behavior=maytrap'}}
   fegetround(); // expected-warning {{'fegetround' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
   fesetround(0); // expected-warning {{'fesetround' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
+  fegetenv(envp); // expected-warning {{'fegetenv' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
+  feholdexcept(envp); // expected-warning {{'feholdexcept' used without 
enabling floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or 
compile with '-ffp-exception-behavior=maytrap'}}
+  fesetenv(envp); // expected-warning {{'fesetenv' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
+  feupdateenv(envp); // expected-warning {{'feupdateenv' used without enabling 
floating-point exception behavior; use 'pragma STDC FENV_ACCESS ON' or compile 
with '-ffp-exception-behavior=maytrap'}}
 #endif
 }
 
 void test_fenv_access_on(void) {
   #pragma STDC FENV_ACCESS ON
+  fesetround(0);
   feclearexcept(FE_INVALID);
+  fegetexceptflag(flagp, FE_INVALID);
   feraiseexcept(FE_INVALID);
+  fesetexceptflag(flagp, FE_INVALID);
   fetestexcept(FE_INVALID);
   fegetround();
   fesetround(0);
+  fegetenv(envp);
+  feholdexcept(envp);
+  fesetenv(envp);
+  feupdateenv(envp);
 }

>From b62c2c112662f65e7a4b1a08afecdb8581062ae9 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:21 +0200
Subject: [PATCH 06/17] Added isPotentiallyEvaluated() check to avoid
 diagnostics inside of decltype() or similar constructs

---
 clang/include/clang/Sema/Sema.h | 4 ++++
 clang/lib/Sema/SemaChecking.cpp | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e71794b2d92c9..62e4c4eb953be 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8264,6 +8264,10 @@ class Sema final : public SemaBase {
     return currentEvaluationContext().isUnevaluated();
   }
 
+  bool isPotentiallyEvaluatedContext() const {
+    return currentEvaluationContext().isPotentiallyEvaluated();
+  }
+
   bool isImmediateFunctionContext() const {
     return currentEvaluationContext().isImmediateFunctionContext();
   }
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 8c4c51f403e93..03091f2ba0cfe 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3941,7 +3941,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
   case Builtin::BIfesetenv:
   case Builtin::BIfeupdateenv:
     if (TheCall->getFPFeaturesInEffect(getLangOpts()).getExceptionMode() ==
-        LangOptions::FPE_Ignore) {
+            LangOptions::FPE_Ignore &&
+        isPotentiallyEvaluatedContext()) {
       Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access)
           << FDecl->getName() << TheCall->getSourceRange();
     }

>From ac99205a0fad10f195d6ad7c507f7db3906eb78a Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:21 +0200
Subject: [PATCH 07/17] Added regression tests for unevaluated occurrences of
 fp exception functions

---
 clang/test/Sema/fenv-access-unevaluated.cpp | 31 +++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 clang/test/Sema/fenv-access-unevaluated.cpp

diff --git a/clang/test/Sema/fenv-access-unevaluated.cpp 
b/clang/test/Sema/fenv-access-unevaluated.cpp
new file mode 100644
index 0000000000000..14752ba3c377e
--- /dev/null
+++ b/clang/test/Sema/fenv-access-unevaluated.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -verify -Wfenv-access %s
+
+typedef struct {} fenv_t;
+typedef unsigned short int fexcept_t;
+
+int feclearexcept(int excepts);
+int fegetexceptflag(fexcept_t *flagp, int excepts);
+int feraiseexcept(int excepts);
+int fesetexceptflag(const fexcept_t *flagp, int excepts);
+int fetestexcept(int excepts);
+int fegetround(void);
+int fesetround(int rounding_mode);
+int fegetenv(fenv_t *envp);
+int feholdexcept(fenv_t *envp);
+int fesetenv(const fenv_t *envp);
+int feupdateenv(const fenv_t *envp);
+
+// expected-no-diagnostics
+void test_fenv_access_unevaluated() {
+  decltype(::feclearexcept) a;
+  decltype(::fegetexceptflag) b;
+  decltype(::feraiseexcept) c;
+  decltype(::fesetexceptflag) d;
+  decltype(::fetestexcept) e;
+  decltype(::fegetround) f;
+  decltype(::fesetround) g;
+  decltype(::fegetenv) h;
+  decltype(::feholdexcept) i;
+  decltype(::fesetenv) j;
+  decltype(::feupdateenv) k;
+}

>From 555678df407fe6345136f2b12835031ffc8e1f66 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:22 +0200
Subject: [PATCH 08/17] Added regression tests for implicit usage of fp
 exception functions

---
 clang/test/Sema/fenv-access-implicit.c | 35 ++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 clang/test/Sema/fenv-access-implicit.c

diff --git a/clang/test/Sema/fenv-access-implicit.c 
b/clang/test/Sema/fenv-access-implicit.c
new file mode 100644
index 0000000000000..0c4bd6b0eb855
--- /dev/null
+++ b/clang/test/Sema/fenv-access-implicit.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -Wfenv-access %s
+
+typedef struct {} fenv_t;
+typedef unsigned short int fexcept_t;
+
+fexcept_t *flagp = 0;
+fenv_t *envp = 0;
+
+#define FE_INVALID 1
+
+void test_fenv_access_undeclared(void) {
+  #pragma STDC FENV_ACCESS ON
+  feclearexcept(FE_INVALID); // expected-note {{include the header <fenv.h> or 
explicitly provide a declaration for 'feclearexcept'}} \
+   expected-error {{call to undeclared library function 'feclearexcept' with 
type 'int (int)'; ISO C99 and later do not support implicit function 
declarations}}
+  fegetexceptflag(flagp, FE_INVALID); // expected-note {{include the header 
<fenv.h> or explicitly provide a declaration for 'fegetexceptflag'}} \
+   expected-error {{call to undeclared library function 'fegetexceptflag' with 
type 'int (fexcept_t *, int)' (aka 'int (unsigned short *, int)'); ISO C99 and 
later do not support implicit function declarations}}
+  feraiseexcept(FE_INVALID); // expected-note {{include the header <fenv.h> or 
explicitly provide a declaration for 'feraiseexcept'}} \
+   expected-error {{call to undeclared library function 'feraiseexcept' with 
type 'int (int)'; ISO C99 and later do not support implicit function 
declarations}}
+  fesetexceptflag(flagp, FE_INVALID); // expected-note {{include the header 
<fenv.h> or explicitly provide a declaration for 'fesetexceptflag'}} \
+   expected-error {{call to undeclared library function 'fesetexceptflag' with 
type 'int (const fexcept_t *, int)' (aka 'int (const unsigned short *, int)'); 
ISO C99 and later do not support implicit function declarations}}
+  fetestexcept(FE_INVALID); // expected-note {{include the header <fenv.h> or 
explicitly provide a declaration for 'fetestexcept'}} \
+   expected-error {{call to undeclared library function 'fetestexcept' with 
type 'int (int)'; ISO C99 and later do not support implicit function 
declarations}}
+  fegetround(); // expected-note {{include the header <fenv.h> or explicitly 
provide a declaration for 'fegetround'}} \
+   expected-error {{call to undeclared library function 'fegetround' with type 
'int (void)'; ISO C99 and later do not support implicit function declarations}}
+  fesetround(0); // expected-note {{include the header <fenv.h> or explicitly 
provide a declaration for 'fesetround'}} \
+   expected-error {{call to undeclared library function 'fesetround' with type 
'int (int)'; ISO C99 and later do not support implicit function declarations}}
+  fegetenv(envp); // expected-note {{include the header <fenv.h> or explicitly 
provide a declaration for 'fegetenv'}} \
+   expected-error {{call to undeclared library function 'fegetenv' with type 
'int (fenv_t *)'; ISO C99 and later do not support implicit function 
declarations}}
+  feholdexcept(envp); // expected-note {{include the header <fenv.h> or 
explicitly provide a declaration for 'feholdexcept'}} \
+   expected-error {{call to undeclared library function 'feholdexcept' with 
type 'int (fenv_t *)'; ISO C99 and later do not support implicit function 
declarations}}
+  fesetenv(envp); // expected-note {{include the header <fenv.h> or explicitly 
provide a declaration for 'fesetenv'}} \
+   expected-error {{call to undeclared library function 'fesetenv' with type 
'int (const fenv_t *)'; ISO C99 and later do not support implicit function 
declarations}}
+  feupdateenv(envp); // expected-note {{include the header <fenv.h> or 
explicitly provide a declaration for 'feupdateenv'}} \
+   expected-error {{call to undeclared library function 'feupdateenv' with 
type 'int (const fenv_t *)'; ISO C99 and later do not support implicit function 
declarations}}
+}

>From f6616616cbc58695ffb9a572225a467a90c72305 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:22 +0200
Subject: [PATCH 09/17] Added regression tests for fexcept_t

---
 clang/test/Sema/builtin-fenv.c | 51 ++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 clang/test/Sema/builtin-fenv.c

diff --git a/clang/test/Sema/builtin-fenv.c b/clang/test/Sema/builtin-fenv.c
new file mode 100644
index 0000000000000..db8a5334d1073
--- /dev/null
+++ b/clang/test/Sema/builtin-fenv.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -verify=c,expected 
-DWRONG_FEXCEPT_T %s -ast-dump | FileCheck %s --check-prefixes=CHECK1,CHECK2
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -verify=c,expected 
-DRIGHT_FEXCEPT_T %s -ast-dump | FileCheck %s --check-prefixes=CHECK1,CHECK2
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -verify=c,expected 
-DONLY_FEXCEPT_T %s -ast-dump | FileCheck %s --check-prefixes=CHECK1,CHECK2
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -verify=c,expected 
-DNO_FEGETEXCEPTFLAG %s -ast-dump 2>&1 | FileCheck %s --check-prefixes=CHECK1
+
+// tests inspired by clang/test/Sema/builtin-setjmp.c
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if WRONG_FEXCEPT_T
+typedef unsigned short int fexcept_t;
+extern int fegetexceptflag(int, int); // c-warning {{incompatible 
redeclaration of library function 'fegetexceptflag'}}
+                                      // c-note@-1 {{'fegetexceptflag' is a 
builtin with type 'int (fexcept_t *, int)' (aka 'int (unsigned short *, int)')}}
+#elif RIGHT_FEXCEPT_T
+// c-no-diagnostics
+typedef unsigned short int fexcept_t;
+extern int fegetexceptflag(unsigned short int *, int); // OK, right type.
+#elif ONLY_FEXCEPT_T
+typedef long *fexcept_t;
+#endif
+
+void use(void) {
+  #pragma STDC FENV_ACCESS ON
+  fegetexceptflag(0, 0);
+  #if NO_FEGETEXCEPTFLAG
+  // cxx-error@-2 {{undeclared identifier 'fegetexceptflag'}}
+  // c-error@-3 {{call to undeclared function 'fegetexceptflag'; ISO C99 and 
later do not support implicit function declarations}}
+  // c-warning@-4 {{declaration of built-in function 'fegetexceptflag' 
requires inclusion of the header <fenv.h>}}
+  #elif ONLY_FEXCEPT_T
+  // cxx-error@-6 {{undeclared identifier 'fegetexceptflag'}}
+  // c-error@-7 {{call to undeclared library function 'fegetexceptflag' with 
type 'int (fexcept_t *, int)' (aka 'int (long **, int)'); ISO C99 and later do 
not support implicit function declarations}}
+  // c-note@-8 {{include the header <fenv.h> or explicitly provide a 
declaration for 'fegetexceptflag'}}
+  #else
+  // cxx-no-diagnostics
+  #endif
+
+  #ifdef NO_FEGETEXCEPTFLAG
+  // In this case, the regular AST dump doesn't dump the implicit declaration 
of 'fegetexceptflag'.
+  #pragma clang __debug dump fegetexceptflag 
+  #endif
+}
+
+// CHECK1: FunctionDecl {{.*}} used fegetexceptflag
+// CHECK2: BuiltinAttr {{.*}} Implicit
+
+
+#ifdef __cplusplus
+}
+#endif

>From eee8e625f52342c904eed6cc3b6e93e8508aede0 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:22 +0200
Subject: [PATCH 10/17] Added regression tests for AST serialization (fenv.h)

---
 clang/test/PCH/builtins-fenv.c | 25 +++++++++++++++++++++++++
 clang/test/PCH/builtins-fenv.h | 18 ++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 clang/test/PCH/builtins-fenv.c
 create mode 100644 clang/test/PCH/builtins-fenv.h

diff --git a/clang/test/PCH/builtins-fenv.c b/clang/test/PCH/builtins-fenv.c
new file mode 100644
index 0000000000000..72bcf4a134730
--- /dev/null
+++ b/clang/test/PCH/builtins-fenv.c
@@ -0,0 +1,25 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/builtins-fenv.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/builtins-fenv.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+// expected-no-diagnostics
+fexcept_t *flagp = 0;
+fenv_t *envp = 0;
+
+void f(void) {
+  #pragma STDC FENV_ACCESS ON
+  feclearexcept(FE_INVALID);
+  fegetexceptflag(flagp, FE_INVALID);
+  feraiseexcept(FE_INVALID);
+  fesetexceptflag(flagp, FE_INVALID);
+  fetestexcept(FE_INVALID);
+  fegetround();
+  fesetround(0);
+  fegetenv(envp);
+  feholdexcept(envp);
+  fesetenv(envp);
+  feupdateenv(envp);
+}
diff --git a/clang/test/PCH/builtins-fenv.h b/clang/test/PCH/builtins-fenv.h
new file mode 100644
index 0000000000000..8397c270df58e
--- /dev/null
+++ b/clang/test/PCH/builtins-fenv.h
@@ -0,0 +1,18 @@
+// Header for PCH test builtins-fenv.c
+
+#define FE_INVALID 1
+
+typedef struct {} fenv_t;
+typedef unsigned short int fexcept_t;
+
+int feclearexcept(int excepts);
+int fegetexceptflag(fexcept_t *flagp, int excepts);
+int feraiseexcept(int excepts);
+int fesetexceptflag(const fexcept_t *flagp, int excepts);
+int fetestexcept(int excepts);
+int fegetround(void);
+int fesetround(int rounding_mode);
+int fegetenv(fenv_t *envp);
+int feholdexcept(fenv_t *envp);
+int fesetenv(const fenv_t *envp);
+int feupdateenv(const fenv_t *envp);

>From c838bb208208745094573db1dd68b18fb6b48fc9 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Wed, 13 May 2026 22:50:23 +0200
Subject: [PATCH 11/17] Add release notes

---
 clang/docs/ReleaseNotes.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6838cf3defcc1..dd78896fefd93 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -544,6 +544,9 @@ Improvements to Clang's diagnostics
   
 - The diagnostics around ``__block`` now explain why a variable cannot be 
marked ``__block``. (#GH197213)
 
+- Added warnings for floating-point exception function calls (fenv.h) without 
enabling
+  floating-point exception behavior via the appropriate flags or pragmas. 
(#GH128239)
+
 Improvements to Clang's time-trace
 ----------------------------------
 

>From 4ec064c763bea29b0f0e515090e0f137340653c4 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Sun, 17 May 2026 22:43:47 +0200
Subject: [PATCH 12/17] Add clang warning if fp exception functions are called
 without appropriate flags/pragmas (#187860)

Fixes https://github.com/llvm/llvm-project/issues/128239

The implementation adds warnings for floating-point exception function
calls (fenv.h) made without enabling floating-point exception behavior
via `-ffp-exception-behavior=maytrap/strict` or `#pragma STDC
FENV_ACCESS ON`. To support recognition of all fenv.h builtins,
`fexcept_t` and `fenv_t` were added as builtin types.
---
 clang/docs/ReleaseNotes.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dd78896fefd93..16a33bf8069d8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -544,6 +544,9 @@ Improvements to Clang's diagnostics
   
 - The diagnostics around ``__block`` now explain why a variable cannot be 
marked ``__block``. (#GH197213)
 
+- Added warnings for floating-point exception function calls (fenv.h) without 
enabling
+  floating-point exception behavior via the appropriate flags or pragmas. 
(#GH128239)
+
 - Added warnings for floating-point exception function calls (fenv.h) without 
enabling
   floating-point exception behavior via the appropriate flags or pragmas. 
(#GH128239)
 

>From 0d7121644916b57e6f4f7fb8b46a03d73607e1ba Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Thu, 21 May 2026 15:10:06 +0200
Subject: [PATCH 13/17] Added check for strict FP support before warning

---
 clang/lib/Sema/SemaChecking.cpp | 4 +++-
 clang/test/Sema/fenv-access.c   | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 03091f2ba0cfe..bcb3d17931d6a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3942,7 +3942,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
   case Builtin::BIfeupdateenv:
     if (TheCall->getFPFeaturesInEffect(getLangOpts()).getExceptionMode() ==
             LangOptions::FPE_Ignore &&
-        isPotentiallyEvaluatedContext()) {
+        isPotentiallyEvaluatedContext() &&
+        (getASTContext().getTargetInfo().hasStrictFP() ||
+         getLangOpts().ExpStrictFP)) {
       Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access)
           << FDecl->getName() << TheCall->getSourceRange();
     }
diff --git a/clang/test/Sema/fenv-access.c b/clang/test/Sema/fenv-access.c
index 3a7b95af7ab4c..50a4d9fd16aa2 100644
--- a/clang/test/Sema/fenv-access.c
+++ b/clang/test/Sema/fenv-access.c
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -verify -Wfenv-access %s
 // RUN: %clang_cc1 -verify -Wfenv-access -ffp-exception-behavior=maytrap 
-DNO_WARN %s
 // RUN: %clang_cc1 -verify -Wfenv-access -ffp-exception-behavior=strict 
-DNO_WARN %s
+// RUN: %clang_cc1 -verify -Wfenv-access -triple armv7-linux-gnueabihf 
-DNO_WARN -DUNSUPPORTED %s
 
 typedef struct {} fenv_t;
 typedef unsigned short int fexcept_t;
@@ -52,7 +53,9 @@ void test_fenv_access_off(void) {
 }
 
 void test_fenv_access_on(void) {
+#ifndef UNSUPPORTED
   #pragma STDC FENV_ACCESS ON
+#endif
   fesetround(0);
   feclearexcept(FE_INVALID);
   fegetexceptflag(flagp, FE_INVALID);

>From 2d1e9686a845117a8c413c3c0f33b794f71beb48 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Thu, 21 May 2026 15:19:25 +0200
Subject: [PATCH 14/17] Removed redundant extern "C" {} block in builtin-fenv.c

---
 clang/test/Sema/builtin-fenv.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/clang/test/Sema/builtin-fenv.c b/clang/test/Sema/builtin-fenv.c
index db8a5334d1073..c9b2306326326 100644
--- a/clang/test/Sema/builtin-fenv.c
+++ b/clang/test/Sema/builtin-fenv.c
@@ -5,10 +5,6 @@
 
 // tests inspired by clang/test/Sema/builtin-setjmp.c
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if WRONG_FEXCEPT_T
 typedef unsigned short int fexcept_t;
 extern int fegetexceptflag(int, int); // c-warning {{incompatible 
redeclaration of library function 'fegetexceptflag'}}
@@ -44,8 +40,3 @@ void use(void) {
 
 // CHECK1: FunctionDecl {{.*}} used fegetexceptflag
 // CHECK2: BuiltinAttr {{.*}} Implicit
-
-
-#ifdef __cplusplus
-}
-#endif

>From 7cd89be5bd341db891d974665c16234b38b74e8a Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Thu, 21 May 2026 15:42:31 +0200
Subject: [PATCH 15/17] Updated ReleaseNotes.rst

---
 clang/docs/ReleaseNotes.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4bf8522443a05..6404894415db6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -546,8 +546,8 @@ Improvements to Clang's diagnostics
 
 - Extended ``-Wnonportable-include-path`` to warn about trailing whitespace 
and dots in ``#include`` paths. (#GH190610)
 
-- Added warnings for floating-point exception function calls (fenv.h) without 
enabling
-  floating-point exception behavior via the appropriate flags or pragmas. 
(#GH128239)
+- Added warnings for floating-point exception function calls (fenv.h) without 
enabling floating-point
+  exception behavior via the appropriate flags or pragmas on supported 
targets. (#GH128239)
 
 Improvements to Clang's time-trace
 ----------------------------------

>From c94885250ae84c089efe32fbefd0038dd31fa8a2 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Thu, 28 May 2026 15:43:09 +0200
Subject: [PATCH 16/17] [libc] Add #pragma STDC FENV_ACCESS ON to FEnvImpl.h
 wrappers

---
 libc/src/__support/FPUtil/FEnvImpl.h | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/FPUtil/FEnvImpl.h 
b/libc/src/__support/FPUtil/FEnvImpl.h
index a21f511bd72b8..208c095170c05 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -37,26 +37,41 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
 
-LIBC_INLINE int clear_except(int excepts) { return feclearexcept(excepts); }
+LIBC_INLINE int clear_except(int excepts) {
+#pragma STDC FENV_ACCESS ON
+  return feclearexcept(excepts);
+}
 
-LIBC_INLINE int test_except(int excepts) { return fetestexcept(excepts); }
+LIBC_INLINE int test_except(int excepts) {
+#pragma STDC FENV_ACCESS ON
+  return fetestexcept(excepts);
+}
 
 LIBC_INLINE int get_except() {
+#pragma STDC FENV_ACCESS ON
   fexcept_t excepts = 0;
   fegetexceptflag(&excepts, FE_ALL_EXCEPT);
   return static_cast<int>(excepts);
 }
 
 LIBC_INLINE int set_except(int excepts) {
+#pragma STDC FENV_ACCESS ON
   fexcept_t exc = static_cast<fexcept_t>(excepts);
   return fesetexceptflag(&exc, FE_ALL_EXCEPT);
 }
 
-LIBC_INLINE int raise_except(int excepts) { return feraiseexcept(excepts); }
+LIBC_INLINE int raise_except(int excepts) {
+#pragma STDC FENV_ACCESS ON
+  return feraiseexcept(excepts);
+}
 
-LIBC_INLINE int get_round() { return fegetround(); }
+LIBC_INLINE int get_round() {
+#pragma STDC FENV_ACCESS ON
+  return fegetround();
+}
 
 LIBC_INLINE int set_round(int rounding_mode) {
+#pragma STDC FENV_ACCESS ON
   return fesetround(rounding_mode);
 }
 
@@ -129,6 +144,7 @@ clear_except_if_required([[maybe_unused]] int excepts) {
     return 0;
   } else {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
+#pragma STDC FENV_ACCESS ON
     if (math_errhandling & MATH_ERREXCEPT)
       return clear_except(excepts);
 #endif // LIBC_MATH_HAS_NO_EXCEPT
@@ -142,6 +158,7 @@ set_except_if_required([[maybe_unused]] int excepts) {
     return 0;
   } else {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
+#pragma STDC FENV_ACCESS ON
     if (math_errhandling & MATH_ERREXCEPT)
       return set_except(excepts);
 #endif // LIBC_MATH_HAS_NO_EXCEPT
@@ -155,6 +172,7 @@ raise_except_if_required([[maybe_unused]] int excepts) {
     return 0;
   } else {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
+#pragma STDC FENV_ACCESS ON
     if (math_errhandling & MATH_ERREXCEPT)
       return raise_except(excepts);
 #endif // LIBC_MATH_HAS_NO_EXCEPT

>From d13a180a553a1359cce22339a1c6ac08faada248 Mon Sep 17 00:00:00 2001
From: Marcos Ramirez Joos <[email protected]>
Date: Thu, 28 May 2026 16:43:48 +0200
Subject: [PATCH 17/17] [libc] Add LIBC_FENV_ACCESS_ON macro to abstract fenv
 pragma per compiler/arch

---
 libc/src/__support/FPUtil/FEnvImpl.h          | 21 +++++-----
 .../macros/properties/CMakeLists.txt          |  9 ++++
 .../macros/properties/fenv_support.h          | 41 +++++++++++++++++++
 3 files changed, 61 insertions(+), 10 deletions(-)
 create mode 100644 libc/src/__support/macros/properties/fenv_support.h

diff --git a/libc/src/__support/FPUtil/FEnvImpl.h 
b/libc/src/__support/FPUtil/FEnvImpl.h
index 208c095170c05..0cbbf183a019c 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -19,6 +19,7 @@
 #include "src/__support/macros/optimization.h"
 #include "src/__support/macros/properties/architectures.h"
 #include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/fenv_support.h"
 
 // In full build mode we are the system fenv in libc.
 #if defined(LIBC_FULL_BUILD)
@@ -38,40 +39,40 @@ namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
 
 LIBC_INLINE int clear_except(int excepts) {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   return feclearexcept(excepts);
 }
 
 LIBC_INLINE int test_except(int excepts) {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   return fetestexcept(excepts);
 }
 
 LIBC_INLINE int get_except() {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   fexcept_t excepts = 0;
   fegetexceptflag(&excepts, FE_ALL_EXCEPT);
   return static_cast<int>(excepts);
 }
 
 LIBC_INLINE int set_except(int excepts) {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   fexcept_t exc = static_cast<fexcept_t>(excepts);
   return fesetexceptflag(&exc, FE_ALL_EXCEPT);
 }
 
 LIBC_INLINE int raise_except(int excepts) {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   return feraiseexcept(excepts);
 }
 
 LIBC_INLINE int get_round() {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   return fegetround();
 }
 
 LIBC_INLINE int set_round(int rounding_mode) {
-#pragma STDC FENV_ACCESS ON
+  LIBC_FENV_ACCESS_ON
   return fesetround(rounding_mode);
 }
 
@@ -144,7 +145,7 @@ clear_except_if_required([[maybe_unused]] int excepts) {
     return 0;
   } else {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
-#pragma STDC FENV_ACCESS ON
+    LIBC_FENV_ACCESS_ON
     if (math_errhandling & MATH_ERREXCEPT)
       return clear_except(excepts);
 #endif // LIBC_MATH_HAS_NO_EXCEPT
@@ -158,7 +159,7 @@ set_except_if_required([[maybe_unused]] int excepts) {
     return 0;
   } else {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
-#pragma STDC FENV_ACCESS ON
+    LIBC_FENV_ACCESS_ON
     if (math_errhandling & MATH_ERREXCEPT)
       return set_except(excepts);
 #endif // LIBC_MATH_HAS_NO_EXCEPT
@@ -172,7 +173,7 @@ raise_except_if_required([[maybe_unused]] int excepts) {
     return 0;
   } else {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
-#pragma STDC FENV_ACCESS ON
+    LIBC_FENV_ACCESS_ON
     if (math_errhandling & MATH_ERREXCEPT)
       return raise_except(excepts);
 #endif // LIBC_MATH_HAS_NO_EXCEPT
diff --git a/libc/src/__support/macros/properties/CMakeLists.txt 
b/libc/src/__support/macros/properties/CMakeLists.txt
index dfa2f9c572492..cdcccc97cbbcc 100644
--- a/libc/src/__support/macros/properties/CMakeLists.txt
+++ b/libc/src/__support/macros/properties/CMakeLists.txt
@@ -48,3 +48,12 @@ add_header_library(
     libc.include.llvm-libc-types.cfloat16
     libc.include.llvm-libc-types.cfloat128
 )
+
+add_header_library(
+  fenv_support
+  HDRS
+    fenv_support.h
+  DEPENDS
+    .architectures
+    .compiler
+)
diff --git a/libc/src/__support/macros/properties/fenv_support.h 
b/libc/src/__support/macros/properties/fenv_support.h
new file mode 100644
index 0000000000000..1bfa57abb0980
--- /dev/null
+++ b/libc/src/__support/macros/properties/fenv_support.h
@@ -0,0 +1,41 @@
+//===-- Compile time enabling of stict floating-point behavior --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FENV_SUPPORT_H
+#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FENV_SUPPORT_H
+
+#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/macros/properties/compiler.h"
+
+// Check target support of strict floating-point behavior
+#if defined(LIBC_TARGET_ARCH_IS_X86_64) ||                                     
\
+    defined(LIBC_TARGET_ARCH_IS_AARCH64) ||                                    
\
+    defined(LIBC_TARGET_ARCH_IS_ARM) ||                                        
\
+    defined(LIBC_TARGET_ARCH_IS_RISCV64) ||                                    
\
+    defined(LIBC_TARGET_ARCH_IS_RISCV32) ||                                    
\
+    defined(LIBC_TARGET_ARCH_IS_SYSTEMZ) ||                                    
\
+    defined(LIBC_TARGET_ARCH_IS_LOONGARCH64)
+#define LIBC_TARGET_HAS_STRICT_FP
+#endif
+
+// Enable strict floating-point behavior on supported targets
+#ifdef LIBC_TARGET_HAS_STRICT_FP
+#if defined(LIBC_COMPILER_IS_CLANG) && LIBC_COMPILER_CLANG_VER > 10
+// Clang >= 10 supports `#pragma clang fp exceptions(maytrap)`, which is the
+// local-scope equivalent of `-ffp-exception-behavior=maytrap` and is what the
+// -Wfenv-access diagnostic recommends.
+#define LIBC_FENV_ACCESS_ON _Pragma("clang fp exceptions(maytrap)")
+#else
+// Portable fallback for GCC, MSVC, or older clang.
+#define LIBC_FENV_ACCESS_ON _Pragma("STDC FENV_ACCESS ON")
+#endif
+#else
+#define LIBC_FENV_ACCESS_ON
+#endif
+
+#endif

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to