llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Marcos Ramirez Joos (maarcosrmz) <details> <summary>Changes</summary> 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`. It is only emitted on targets where strict floating-point behavior is supported. Recognizing all fenv.h builtins required adding `fexcept_t` and `fenv_t` as builtin types. --- Patch is 26.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/199009.diff 20 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+3) - (modified) clang/include/clang/AST/ASTContext.h (+34-1) - (modified) clang/include/clang/Basic/BuiltinHeaders.def (+1) - (modified) clang/include/clang/Basic/Builtins.td (+55) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+5) - (modified) clang/include/clang/Basic/TokenKinds.def (+2) - (modified) clang/include/clang/Sema/Sema.h (+4) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+7-1) - (modified) clang/lib/AST/ASTContext.cpp (+19) - (modified) clang/lib/Sema/SemaChecking.cpp (+20) - (modified) clang/lib/Sema/SemaDecl.cpp (+8) - (modified) clang/lib/Serialization/ASTReader.cpp (+36) - (modified) clang/lib/Serialization/ASTWriter.cpp (+2) - (added) clang/test/PCH/builtins-fenv.c (+25) - (added) clang/test/PCH/builtins-fenv.h (+18) - (added) clang/test/Sema/builtin-fenv.c (+42) - (added) clang/test/Sema/fenv-access-implicit.c (+35) - (added) clang/test/Sema/fenv-access-unevaluated.cpp (+31) - (added) clang/test/Sema/fenv-access.c (+71) - (modified) clang/utils/TableGen/ClangBuiltinsEmitter.cpp (+2) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index e4f992f6e0f08..9fd529e874fa5 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -679,6 +679,9 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the by the kernel, so setting them is almost always a typo (matching the bionic libc `diagnose_if` check). +- 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 ### Improvements to Coverage Mapping diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index a4ed852d36442..763e4df87f08a 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -495,6 +495,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 @@ -2360,6 +2366,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; @@ -2640,7 +2670,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/BuiltinHeaders.def b/clang/include/clang/Basic/BuiltinHeaders.def index b18e470a8bd25..d47803aafafa7 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 506f47fb597af..3f057b5f1cf68 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4696,6 +4696,61 @@ def BlockObjectDispose : LibBuiltin<"blocks.h"> { } // FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock. +def FeClearExcept : LibBuiltin<"fenv.h"> { + let Spellings = ["feclearexcept"]; + 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)"; +} + +def FeGetRound : LibBuiltin<"fenv.h"> { + let Spellings = ["fegetround"]; + let Prototype = "int()"; +} + +def FeSetRound : LibBuiltin<"fenv.h"> { + let Spellings = ["fesetround"]; + 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/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 86b765fdf1fab..fb149ebcdd8ec 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1053,6 +1053,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/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/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ebb775ffbb758..38e09dae1e9d5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8259,6 +8259,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/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 279380de2f7fe..d323bcc79bab8 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1217,7 +1217,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 abf0cd5e18c2b..a700143d1ba47 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -12921,6 +12921,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/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 01b1f4c26f017..e7e3f79fa2192 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4146,6 +4146,26 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (BuiltinCountedByRef(TheCall)) return ExprError(); 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 && + isPotentiallyEvaluatedContext() && + (getASTContext().getTargetInfo().hasStrictFP() || + getLangOpts().ExpStrictFP)) { + Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access) + << FDecl->getName() << TheCall->getSourceRange(); + } } if (getLangOpts().HLSL && HLSL().CheckBuiltinFunctionCall(BuiltinID, TheCall)) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f6d1d7a7877c7..1edce35b03697 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 b01b18fe3e0ec..a5d426a43cd08 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 ecf935e3b3548..2ba75b8184ce9 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6137,6 +6137,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/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); diff --git a/clang/test/Sema/builtin-fenv.c b/clang/test/Sema/builtin-fenv.c new file mode 100644 index 0000000000000..c9b2306326326 --- /dev/null +++ b/clang/test/Sema/builtin-fenv.c @@ -0,0 +1,42 @@ +// 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 + +#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 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-no... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/199009 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
