From 7dbaf037b6b2196cee7c0c837e0a89ce3c2556ed Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Wed, 3 Jan 2024 14:37:17 -0800 Subject: [PATCH 01/10] [CLANG] Add warning when comparing to INF or NAN in fast math mode. --- .../clang/Basic/DiagnosticSemaKinds.td | 3 + clang/include/clang/Sema/Sema.h | 4 + clang/lib/Sema/SemaChecking.cpp | 65 +++++++ clang/lib/Sema/SemaExpr.cpp | 7 +- clang/test/Sema/warn-fp-fast-compare.cpp | 171 ++++++++++++++++++ 5 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 clang/test/Sema/warn-fp-fast-compare.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e54f969c19039..1b75ae8f678b6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6771,6 +6771,9 @@ def warn_pointer_sub_null_ptr : Warning< def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; +def warn_fast_floatingpoint_eq : Warning< + "explicit comparison with %0 in fast floating point mode">, + InGroup; def err_setting_eval_method_used_in_unsafe_context : Error < "%select{'#pragma clang fp eval_method'|option 'ffp-eval-method'}0 cannot be used with " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5e3b57ea33220..6125e7ebb6b48 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13998,6 +13998,8 @@ class Sema final { SourceRange range, llvm::SmallBitVector &CheckedVarArgs); + void CheckInfNaNFunction(const CallExpr *Call, const FunctionDecl *FDecl); + void CheckAbsoluteValueFunction(const CallExpr *Call, const FunctionDecl *FDecl); @@ -14024,6 +14026,8 @@ class Sema final { public: void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode); + void CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, + BinaryOperatorKind Opcode); private: void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3168d38dd66c3..2e9f61f40b795 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2169,6 +2169,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, ICEArguments &= ~(1 << ArgNo); } + FPOptions FPO; switch (BuiltinID) { case Builtin::BI__builtin___CFStringMakeConstantString: // CFStringMakeConstantString is currently not implemented for GOFF (i.e., @@ -2245,6 +2246,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_islessequal: case Builtin::BI__builtin_islessgreater: case Builtin::BI__builtin_isunordered: + if (BuiltinID == Builtin::BI__builtin_isunordered) { + if (TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "NaN" << TheCall->getSourceRange(); + } if (SemaBuiltinUnorderedCompare(TheCall)) return ExprError(); break; @@ -2267,6 +2273,16 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_signbit: case Builtin::BI__builtin_signbitf: case Builtin::BI__builtin_signbitl: + FPO = TheCall->getFPFeaturesInEffect(getLangOpts()); + if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || + BuiltinID == Builtin::BI__builtin_isinf || + BuiltinID == Builtin::BI__builtin_isinf_sign)) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "infinity" << TheCall->getSourceRange(); + if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || + BuiltinID == Builtin::BI__builtin_isunordered)) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "NaN" << TheCall->getSourceRange(); if (SemaBuiltinFPClassification(TheCall, 1)) return ExprError(); break; @@ -7621,6 +7637,7 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, CheckAbsoluteValueFunction(TheCall, FDecl); CheckMaxUnsignedZero(TheCall, FDecl); + CheckInfNaNFunction(TheCall, FDecl); if (getLangOpts().ObjC) DiagnoseCStringFormatDirectiveInCFAPI(*this, FDecl, Args, NumArgs); @@ -12878,6 +12895,23 @@ static bool IsStdFunction(const FunctionDecl *FDecl, return true; } +void Sema::CheckInfNaNFunction(const CallExpr *Call, + const FunctionDecl *FDecl) { + if (Call->getNumArgs() != 1 && Call->getNumArgs() != 2) + return; + + FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts()); + if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered")) && + FPO.getNoHonorNaNs()) + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "NaN" << Call->getSourceRange(); + else if ((IsStdFunction(FDecl, "isinf") || + (IsStdFunction(FDecl, "isfinite"))) && + FPO.getNoHonorInfs()) + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "infinity" << Call->getSourceRange(); +} + // Warn when using the wrong abs() function. void Sema::CheckAbsoluteValueFunction(const CallExpr *Call, const FunctionDecl *FDecl) { @@ -13846,6 +13880,37 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, CheckPPCMMAType(RetValExp->getType(), ReturnLoc); } +/// Diagnose comparison to NAN or INFINITY in fast math modes. +/// The comparison to NaN or INFINITY is always false in +/// fast modes: float evaluation will not result in inf or nan. +void Sema::CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, + BinaryOperatorKind Opcode) { + Expr *LeftExprSansParen = LHS->IgnoreParenImpCasts(); + Expr *RightExprSansParen = RHS->IgnoreParenImpCasts(); + + FPOptions FPO = LHS->getFPFeaturesInEffect(getLangOpts()); + bool NoHonorNaNs = FPO.getNoHonorNaNs(); + bool NoHonorInfs = FPO.getNoHonorInfs(); + llvm::APFloat Value(0.0); + bool IsConstant; + IsConstant = !LHS->isValueDependent() && + LeftExprSansParen->EvaluateAsFloat(Value, Context, + Expr::SE_AllowSideEffects); + if (IsConstant && + ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) + Diag(Loc, diag::warn_fast_floatingpoint_eq) + << (Value.isNaN() ? "NaN" : "infinity") << LHS->getSourceRange() + << RHS->getSourceRange(); + IsConstant = !RHS->isValueDependent() && + RightExprSansParen->EvaluateAsFloat(Value, Context, + Expr::SE_AllowSideEffects); + if (IsConstant && + ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) + Diag(Loc, diag::warn_fast_floatingpoint_eq) + << (Value.isNaN() ? "NaN" : "infinity") << LHS->getSourceRange() + << RHS->getSourceRange(); +} + /// Check for comparisons of floating-point values using == and !=. Issue a /// warning if the comparison is not likely to do what the programmer intended. void Sema::CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 960f513d1111b..005ddfa882195 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13044,9 +13044,12 @@ static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS, if (Type->isAnyComplexType() && BinaryOperator::isRelationalOp(Opc)) return S.InvalidOperands(Loc, LHS, RHS); - // Check for comparisons of floating point operands using != and ==. - if (Type->hasFloatingRepresentation()) + if (Type->hasFloatingRepresentation()) { + // Check for comparisons to NAN or INFINITY in fast math mode. + S.CheckInfNaNFloatComparison(Loc, LHS.get(), RHS.get(), Opc); + // Check for comparisons of floating point operands using != and ==. S.CheckFloatComparison(Loc, LHS.get(), RHS.get(), Opc); + } // The result of comparisons is 'bool' in C++, 'int' in C. return S.Context.getLogicalOperationType(); diff --git a/clang/test/Sema/warn-fp-fast-compare.cpp b/clang/test/Sema/warn-fp-fast-compare.cpp new file mode 100644 index 0000000000000..07eeaf0eeab12 --- /dev/null +++ b/clang/test/Sema/warn-fp-fast-compare.cpp @@ -0,0 +1,171 @@ +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans -DFAST=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -DNOFAST=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -DNO_INFS=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-nans -DNO_NANS=1 + +int isunorderedf (float x, float y); +#if NOFAST +// expected-no-diagnostics +#endif +extern "C++" { +namespace std __attribute__((__visibility__("default"))) { + bool + isinf(float __x); + bool + isinf(double __x); + bool + isinf(long double __x); + bool + isnan(float __x); + bool + isnan(double __x); + bool + isnan(long double __x); +bool + isfinite(float __x); + bool + isfinite(double __x); + bool + isfinte(long double __x); + bool + isunordered(float __x, float __y); + bool + isunordered(double __x, double __y); + bool + isunordered(long double __x, long double __y); +} // namespace ) +} +#define NAN (__builtin_nanf("")) +#define INFINITY (__builtin_inff()) + +int compareit(float a, float b) { + volatile int i, j, k, l, m, n, o, p; +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + i = a == INFINITY; +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + j = INFINITY == a; +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + i = a == NAN; +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + j = NAN == a; +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + j = INFINITY <= a; +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + j = INFINITY < a; +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + j = a > NAN; +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + j = a >= NAN; +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif +k = std::isinf(a); +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + l = std::isnan(a); +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +//expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + o = std::isfinite(a); +#if FAST +// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + m = __builtin_isinf(a); +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + n = __builtin_isnan(a); +#if FAST +//expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +#endif +#if NO_INFS +//expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +#endif + p = __builtin_isfinite(a); + + // These should NOT warn, since they are not comparing with NaN or infinity. + j = a > 1.1; + j = b < 1.1; + j = a >= 1.1; + j = b <= 1.1; + j = isunorderedf(a, NAN); + j = isunorderedf(a, INFINITY); +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + i = std::isunordered(a, NAN); +#if FAST +// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +#endif + i = std::isunordered(a, INFINITY); + return 0; +} From f4aa37980d861617719b3f027f69e652c0502515 Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Fri, 5 Jan 2024 13:54:42 -0800 Subject: [PATCH 02/10] Addressed review comments. --- .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/include/clang/Sema/Sema.h | 5 +- clang/lib/Sema/SemaChecking.cpp | 73 ++++----- clang/test/Sema/warn-fp-fast-compare.cpp | 138 ++++++++++++++---- 4 files changed, 148 insertions(+), 70 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1b75ae8f678b6..d19be567a1bf6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6772,7 +6772,7 @@ def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; def warn_fast_floatingpoint_eq : Warning< - "explicit comparison with %0 in fast floating point mode">, + "explicit comparison with %0 when the program is assumed to not use or produce %0">, InGroup; def err_setting_eval_method_used_in_unsafe_context : Error < diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6125e7ebb6b48..b19ce6312e83b 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13893,8 +13893,9 @@ class Sema final { bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call); - bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); - bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); + bool SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID); + bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, + unsigned BuiltinID); bool SemaBuiltinComplex(CallExpr *TheCall); bool SemaBuiltinVSX(CallExpr *TheCall); bool SemaBuiltinOSLogFormat(CallExpr *TheCall); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2e9f61f40b795..2c4d628ab160d 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2246,20 +2246,15 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_islessequal: case Builtin::BI__builtin_islessgreater: case Builtin::BI__builtin_isunordered: - if (BuiltinID == Builtin::BI__builtin_isunordered) { - if (TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "NaN" << TheCall->getSourceRange(); - } - if (SemaBuiltinUnorderedCompare(TheCall)) + if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID)) return ExprError(); break; case Builtin::BI__builtin_fpclassify: - if (SemaBuiltinFPClassification(TheCall, 6)) + if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID)) return ExprError(); break; case Builtin::BI__builtin_isfpclass: - if (SemaBuiltinFPClassification(TheCall, 2)) + if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID)) return ExprError(); break; case Builtin::BI__builtin_isfinite: @@ -2273,17 +2268,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_signbit: case Builtin::BI__builtin_signbitf: case Builtin::BI__builtin_signbitl: - FPO = TheCall->getFPFeaturesInEffect(getLangOpts()); - if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || - BuiltinID == Builtin::BI__builtin_isinf || - BuiltinID == Builtin::BI__builtin_isinf_sign)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "infinity" << TheCall->getSourceRange(); - if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || - BuiltinID == Builtin::BI__builtin_isunordered)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "NaN" << TheCall->getSourceRange(); - if (SemaBuiltinFPClassification(TheCall, 1)) + if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID)) return ExprError(); break; case Builtin::BI__builtin_shufflevector: @@ -9107,10 +9092,16 @@ bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) { /// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and /// friends. This is declared to take (...), so we have to check everything. -bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { +bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { if (checkArgCount(*this, TheCall, 2)) return true; + if (BuiltinID == Builtin::BI__builtin_isunordered) { + if (TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "NaN" << TheCall->getSourceRange(); + } + ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -9145,10 +9136,22 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { /// SemaBuiltinSemaBuiltinFPClassification - Handle functions like /// __builtin_isnan and friends. This is declared to take (...), so we have /// to check everything. -bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) { +bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, + unsigned BuiltinID) { if (checkArgCount(*this, TheCall, NumArgs)) return true; + FPOptions FPO = TheCall->getFPFeaturesInEffect(getLangOpts()); + if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || + BuiltinID == Builtin::BI__builtin_isinf || + BuiltinID == Builtin::BI__builtin_isinf_sign)) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "infinity" << TheCall->getSourceRange(); + if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || + BuiltinID == Builtin::BI__builtin_isunordered)) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << "NaN" << TheCall->getSourceRange(); + bool IsFPClass = NumArgs == 2; // Find out position of floating-point argument. @@ -12897,16 +12900,15 @@ static bool IsStdFunction(const FunctionDecl *FDecl, void Sema::CheckInfNaNFunction(const CallExpr *Call, const FunctionDecl *FDecl) { - if (Call->getNumArgs() != 1 && Call->getNumArgs() != 2) - return; - FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts()); - if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered")) && + if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || + (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && FPO.getNoHonorNaNs()) Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << "NaN" << Call->getSourceRange(); else if ((IsStdFunction(FDecl, "isinf") || - (IsStdFunction(FDecl, "isfinite"))) && + (IsStdFunction(FDecl, "isfinite") || + (Call->getBuiltinCallee() == Builtin::BI__builtin_inff))) && FPO.getNoHonorInfs()) Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << "infinity" << Call->getSourceRange(); @@ -13892,19 +13894,20 @@ void Sema::CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, bool NoHonorNaNs = FPO.getNoHonorNaNs(); bool NoHonorInfs = FPO.getNoHonorInfs(); llvm::APFloat Value(0.0); - bool IsConstant; - IsConstant = !LHS->isValueDependent() && - LeftExprSansParen->EvaluateAsFloat(Value, Context, - Expr::SE_AllowSideEffects); - if (IsConstant && + + auto IsConstant = [&Value](Expr *E, Expr *ESansParen, ASTContext &Context) { + return !E->isValueDependent() && + ESansParen->EvaluateAsFloat(Value, Context, + Expr::SE_AllowSideEffects); + }; + + if (IsConstant(LHS, LeftExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) << (Value.isNaN() ? "NaN" : "infinity") << LHS->getSourceRange() << RHS->getSourceRange(); - IsConstant = !RHS->isValueDependent() && - RightExprSansParen->EvaluateAsFloat(Value, Context, - Expr::SE_AllowSideEffects); - if (IsConstant && + + if (IsConstant(RHS, RightExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) << (Value.isNaN() ? "NaN" : "infinity") << LHS->getSourceRange() diff --git a/clang/test/Sema/warn-fp-fast-compare.cpp b/clang/test/Sema/warn-fp-fast-compare.cpp index 07eeaf0eeab12..df8c8145f538a 100644 --- a/clang/test/Sema/warn-fp-fast-compare.cpp +++ b/clang/test/Sema/warn-fp-fast-compare.cpp @@ -48,101 +48,149 @@ bool int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if NO_INFS +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif i = a == INFINITY; #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif j = INFINITY == a; #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif i = a == NAN; #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_NANS +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif j = NAN == a; #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if NO_INFS +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} + // expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif j = INFINITY < a; #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_NANS +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} + // expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif j = a > NAN; #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_NANS +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif k = std::isinf(a); #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -//expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif n = __builtin_isnan(a); #if FAST -//expected-warning@+5 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif #if NO_INFS -//expected-warning@+2 {{explicit comparison with infinity in fast floating point mode}} +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif p = __builtin_isfinite(a); @@ -151,20 +199,46 @@ k = std::isinf(a); j = b < 1.1; j = a >= 1.1; j = b <= 1.1; + j = isunorderedf(a, b); + +#if FAST +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif j = isunorderedf(a, NAN); +#if FAST +// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_NANS +// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+5 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +#endif +#if FAST +// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN in fast floating point mode}} +// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +#endif +#if NO_INFS +// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} #endif i = std::isunordered(a, INFINITY); return 0; From 948ace771f6e696c8246789f11248ee0d237a623 Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Thu, 11 Jan 2024 12:47:03 -0800 Subject: [PATCH 03/10] Addressed review comments. --- .../clang/Basic/DiagnosticSemaKinds.td | 4 +- clang/lib/Sema/SemaChecking.cpp | 29 ++-- clang/test/Sema/warn-fp-fast-compare.cpp | 151 +++++++++++------- 3 files changed, 109 insertions(+), 75 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d19be567a1bf6..e1164ef34a1b6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6772,7 +6772,9 @@ def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; def warn_fast_floatingpoint_eq : Warning< - "explicit comparison with %0 when the program is assumed to not use or produce %0">, + "use of %select{infinity|NaN}0 will always be 'false' because " + "%select{infinity|NaN}0 will not be produced according to the currently " + "enabled floating-point options">, InGroup; def err_setting_eval_method_used_in_unsafe_context : Error < diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2c4d628ab160d..027cfac1c5a64 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9096,11 +9096,9 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { if (checkArgCount(*this, TheCall, 2)) return true; - if (BuiltinID == Builtin::BI__builtin_isunordered) { - if (TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "NaN" << TheCall->getSourceRange(); - } + if (BuiltinID == Builtin::BI__builtin_isunordered && + TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1; ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -9145,12 +9143,10 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || BuiltinID == Builtin::BI__builtin_isinf || BuiltinID == Builtin::BI__builtin_isinf_sign)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "infinity" << TheCall->getSourceRange(); + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 0; if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || BuiltinID == Builtin::BI__builtin_isunordered)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "NaN" << TheCall->getSourceRange(); + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1; bool IsFPClass = NumArgs == 2; @@ -12904,14 +12900,13 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && FPO.getNoHonorNaNs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "NaN" << Call->getSourceRange(); + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1; else if ((IsStdFunction(FDecl, "isinf") || (IsStdFunction(FDecl, "isfinite") || - (Call->getBuiltinCallee() == Builtin::BI__builtin_inff))) && + (Call->getBuiltinCallee() == Builtin::BI__builtin_inff)) || + (FDecl->getIdentifier() && FDecl->getName() == "infinity")) && FPO.getNoHonorInfs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << "infinity" << Call->getSourceRange(); + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 0; } // Warn when using the wrong abs() function. @@ -13904,14 +13899,12 @@ void Sema::CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, if (IsConstant(LHS, LeftExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) - << (Value.isNaN() ? "NaN" : "infinity") << LHS->getSourceRange() - << RHS->getSourceRange(); + << (Value.isNaN() ? 1 : 0) << (Value.isNaN() ? 1 : 0); if (IsConstant(RHS, RightExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) - << (Value.isNaN() ? "NaN" : "infinity") << LHS->getSourceRange() - << RHS->getSourceRange(); + << (Value.isNaN() ? 1 : 0) << (Value.isNaN() ? 1 : 0); } /// Check for comparisons of floating-point values using == and !=. Issue a diff --git a/clang/test/Sema/warn-fp-fast-compare.cpp b/clang/test/Sema/warn-fp-fast-compare.cpp index df8c8145f538a..430fb58dfd747 100644 --- a/clang/test/Sema/warn-fp-fast-compare.cpp +++ b/clang/test/Sema/warn-fp-fast-compare.cpp @@ -45,152 +45,175 @@ bool #define NAN (__builtin_nanf("")) #define INFINITY (__builtin_inff()) +template +class numeric_limits { +public: + [[nodiscard]] static constexpr _Ty infinity() noexcept { + return _Ty(); + } +}; + +template <> +class numeric_limits { +public: + [[nodiscard]] static constexpr float infinity() noexcept { + return __builtin_huge_val(); + } +}; +template <> +class numeric_limits { +public: + [[nodiscard]] static constexpr double infinity() noexcept { + return __builtin_huge_val(); + } +}; + int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif i = a == INFINITY; #if FAST -// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = INFINITY == a; #if FAST -// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif i = a == NAN; #if FAST -// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif j = NAN == a; #if FAST -// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS - // expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} + // expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = INFINITY < a; #if FAST -// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS - // expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} + // expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif j = a > NAN; #if FAST -// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif k = std::isinf(a); #if FAST -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif n = __builtin_isnan(a); #if FAST -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif p = __builtin_isfinite(a); @@ -202,44 +225,60 @@ k = std::isinf(a); j = isunorderedf(a, b); #if FAST -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif j = isunorderedf(a, NAN); #if FAST -// expected-warning@+5 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+11 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+11 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{explicit comparison with NaN when the program is assumed to not use or produce NaN}} +// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity when the program is assumed to not use or produce infinity}} +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif i = std::isunordered(a, INFINITY); +#if FAST +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +#endif + double y = i * numeric_limits::infinity(); + +#if FAST +// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +#endif + j = numeric_limits::infinity(); return 0; + } From d82f5690f4811552241b22b425de30dfbc84b049 Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Sat, 13 Jan 2024 08:16:01 -0800 Subject: [PATCH 04/10] Fixed the diagnostic message. --- clang/docs/ReleaseNotes.rst | 4 + .../clang/Basic/DiagnosticSemaKinds.td | 7 +- clang/lib/Sema/SemaChecking.cpp | 14 +- clang/test/Sema/warn-fp-fast-compare.cpp | 126 +++++++++--------- 4 files changed, 78 insertions(+), 73 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 778ce0e0e52d0..94a91e3b13dcb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -519,6 +519,10 @@ Improvements to Clang's diagnostics - Clang now diagnoses narrowing conversions involving const references. (`#63151: `_). - Clang now diagnoses unexpanded packs within the template argument lists of function template specializations. +- Clang's ``-Wtautological-logical-constant-compare`` flag now diagnoses + when ``INFINITY`` or ``NAN`` are used in arithmetic operations or function + arguments in floating-points mode where ``INFINITY`` or ``NAN`` don't have the + expected values. Improvements to Clang's time-trace diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e1164ef34a1b6..856022f51fad7 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6772,9 +6772,10 @@ def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; def warn_fast_floatingpoint_eq : Warning< - "use of %select{infinity|NaN}0 will always be 'false' because " - "%select{infinity|NaN}0 will not be produced according to the currently " - "enabled floating-point options">, + "%select{explicit comparison with|use of}0 %select{infinity|nan}1 " + "%select{will always return 'false'|as a function argument will not always be interpreted as such}0 " + "because %select{infinity|nan}1 will not be produced according to the " + "currently enabled floating-point options">, InGroup; def err_setting_eval_method_used_in_unsafe_context : Error < diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 027cfac1c5a64..f2a49f89b9b1e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9098,7 +9098,7 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { if (BuiltinID == Builtin::BI__builtin_isunordered && TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1; + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 1 << 0 << 1; ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -9143,10 +9143,10 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || BuiltinID == Builtin::BI__builtin_isinf || BuiltinID == Builtin::BI__builtin_isinf_sign)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 0; + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 0 << 0 << 0; if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || BuiltinID == Builtin::BI__builtin_isunordered)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1; + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1 << 1 << 1; bool IsFPClass = NumArgs == 2; @@ -12900,13 +12900,13 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && FPO.getNoHonorNaNs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1; + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1 << 1 << 1; else if ((IsStdFunction(FDecl, "isinf") || (IsStdFunction(FDecl, "isfinite") || (Call->getBuiltinCallee() == Builtin::BI__builtin_inff)) || (FDecl->getIdentifier() && FDecl->getName() == "infinity")) && FPO.getNoHonorInfs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 0; + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 0 << 1 << 0; } // Warn when using the wrong abs() function. @@ -13899,12 +13899,12 @@ void Sema::CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, if (IsConstant(LHS, LeftExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) - << (Value.isNaN() ? 1 : 0) << (Value.isNaN() ? 1 : 0); + << 0 << (Value.isNaN() ? 1 : 0) << 0 << (Value.isNaN() ? 1 : 0); if (IsConstant(RHS, RightExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) - << (Value.isNaN() ? 1 : 0) << (Value.isNaN() ? 1 : 0); + << 0 << (Value.isNaN() ? 1 : 0) << 0 << (Value.isNaN() ? 1 : 0); } /// Check for comparisons of floating-point values using == and !=. Issue a diff --git a/clang/test/Sema/warn-fp-fast-compare.cpp b/clang/test/Sema/warn-fp-fast-compare.cpp index 430fb58dfd747..c6f746c3f8de1 100644 --- a/clang/test/Sema/warn-fp-fast-compare.cpp +++ b/clang/test/Sema/warn-fp-fast-compare.cpp @@ -71,149 +71,149 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif i = a == INFINITY; #if FAST -// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = INFINITY == a; #if FAST -// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif i = a == NAN; #if FAST -// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif j = NAN == a; #if FAST -// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS - // expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif j = INFINITY < a; #if FAST -// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS - // expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif j = a > NAN; #if FAST -// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif -k = std::isinf(a); + k = std::isinf(a); #if FAST -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif n = __builtin_isnan(a); #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} #endif p = __builtin_isfinite(a); @@ -225,58 +225,58 @@ k = std::isinf(a); j = isunorderedf(a, b); #if FAST -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif j = isunorderedf(a, NAN); #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+11 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+11 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of NaN will always be 'false' because NaN will not be produced according to the currently enabled floating-point options}} +// expected-warning@+8 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} #endif i = std::isunordered(a, INFINITY); #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif double y = i * numeric_limits::infinity(); #if FAST -// expected-warning@+5 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity will always be 'false' because infinity will not be produced according to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} #endif j = numeric_limits::infinity(); return 0; From b603724027071ae75ce509f69c3dbb8445edd42f Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Sat, 13 Jan 2024 08:23:24 -0800 Subject: [PATCH 05/10] Fix format. --- clang/lib/Sema/SemaChecking.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f2a49f89b9b1e..4a8078a772006 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9098,7 +9098,8 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { if (BuiltinID == Builtin::BI__builtin_isunordered && TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 1 << 0 << 1; + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << 0 << 1 << 0 << 1; ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -9143,10 +9144,12 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || BuiltinID == Builtin::BI__builtin_isinf || BuiltinID == Builtin::BI__builtin_isinf_sign)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 0 << 0 << 0 << 0; + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << 0 << 0 << 0 << 0; if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || BuiltinID == Builtin::BI__builtin_isunordered)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1 << 1 << 1; + Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << 1 << 1 << 1 << 1; bool IsFPClass = NumArgs == 2; @@ -12900,13 +12903,15 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && FPO.getNoHonorNaNs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 1 << 1 << 1; + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << 1 << 1 << 1 << 1; else if ((IsStdFunction(FDecl, "isinf") || (IsStdFunction(FDecl, "isfinite") || (Call->getBuiltinCallee() == Builtin::BI__builtin_inff)) || (FDecl->getIdentifier() && FDecl->getName() == "infinity")) && FPO.getNoHonorInfs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) << 1 << 0 << 1 << 0; + Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) + << 1 << 0 << 1 << 0; } // Warn when using the wrong abs() function. @@ -13904,7 +13909,7 @@ void Sema::CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, if (IsConstant(RHS, RightExprSansParen, Context) && ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) Diag(Loc, diag::warn_fast_floatingpoint_eq) - << 0 << (Value.isNaN() ? 1 : 0) << 0 << (Value.isNaN() ? 1 : 0); + << 0 << (Value.isNaN() ? 1 : 0) << 0 << (Value.isNaN() ? 1 : 0); } /// Check for comparisons of floating-point values using == and !=. Issue a From 0b2cec264b4cb90088774bb13c35995104975f36 Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Wed, 17 Jan 2024 12:23:06 -0800 Subject: [PATCH 06/10] After discussion with Aaron separated the warning so one is triggered when INFINITY/NAN macros are used and the other when __builtin_inf() and __builtin_nan() are used. --- .../clang/Basic/DiagnosticCommonKinds.td | 5 +- .../clang/Basic/DiagnosticSemaKinds.td | 8 +- clang/include/clang/Lex/Preprocessor.h | 4 + clang/include/clang/Sema/Sema.h | 2 - clang/lib/Lex/Preprocessor.cpp | 5 + clang/lib/Sema/SemaChecking.cpp | 54 +--- clang/lib/Sema/SemaExpr.cpp | 5 +- clang/test/Sema/warn-fp-fast-compare.cpp | 284 ------------------ .../Sema/warn-infinity-nan-disabled-lnx.cpp | 237 +++++++++++++++ .../Sema/warn-infinity-nan-disabled-win.cpp | 240 +++++++++++++++ 10 files changed, 506 insertions(+), 338 deletions(-) delete mode 100644 clang/test/Sema/warn-fp-fast-compare.cpp create mode 100644 clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp create mode 100644 clang/test/Sema/warn-infinity-nan-disabled-win.cpp diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 72952b08c04a4..8c096568ebd45 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -69,7 +69,10 @@ def warn_pragma_debug_missing_argument : Warning< "missing argument to debug command '%0'">, InGroup; def warn_pragma_debug_unexpected_argument : Warning< "unexpected argument to debug command">, InGroup; - +def warn_infinity_defined_in_macro : Warning< + "infinity defined via a macro will result in an undefined behavior " + "due to the currently enabled floating-point options">, + InGroup>; } // Parse && Sema diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 865b9db0f5e93..070986aa45313 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6784,12 +6784,10 @@ def warn_pointer_sub_null_ptr : Warning< def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; -def warn_fast_floatingpoint_eq : Warning< - "%select{explicit comparison with|use of}0 %select{infinity|nan}1 " - "%select{will always return 'false'|as a function argument will not always be interpreted as such}0 " - "because %select{infinity|nan}1 will not be produced according to the " +def warn_fp_nan_inf_when_disabled : Warning< + "use of %select{infinity|NaN}0 results in undefined behavior due to the " "currently enabled floating-point options">, - InGroup; + InGroup>; def err_setting_eval_method_used_in_unsafe_context : Error < "%select{'#pragma clang fp eval_method'|option 'ffp-eval-method'}0 cannot be used with " diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4ec21a8b6be2c..4ad034c02d6b1 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2835,6 +2835,9 @@ class Preprocessor { if (Identifier.getIdentifierInfo()->isRestrictExpansion() && !SourceMgr.isInMainFile(Identifier.getLocation())) emitRestrictExpansionWarning(Identifier); + + if (Identifier.getIdentifierInfo()->getName() == "INFINITY") + emitRestrictInfNaNWarning(Identifier); } static void processPathForFileMacro(SmallVectorImpl &Path, @@ -2850,6 +2853,7 @@ class Preprocessor { void emitMacroDeprecationWarning(const Token &Identifier) const; void emitRestrictExpansionWarning(const Token &Identifier) const; void emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const; + void emitRestrictInfNaNWarning(const Token &Identifier) const; /// This boolean state keeps track if the current scanned token (by this PP) /// is in an "-Wunsafe-buffer-usage" opt-out region. Assuming PP scans a diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a9d720f97ff08..8d915c8c730ea 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14035,8 +14035,6 @@ class Sema final { public: void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode); - void CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, - BinaryOperatorKind Opcode); private: void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 64f54c6fc6382..da8e57ff08402 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -1457,6 +1457,11 @@ void Preprocessor::emitRestrictExpansionWarning(const Token &Identifier) const { Diag(Info.Location, diag::note_pp_macro_annotation) << 1; } +void Preprocessor::emitRestrictInfNaNWarning(const Token &Identifier) const { + if (getLangOpts().NoHonorInfs) + Diag(Identifier, diag::warn_infinity_defined_in_macro); +} + void Preprocessor::emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const { const MacroAnnotations &A = diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index bd29318ce893d..6195d0b361a78 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9113,8 +9113,8 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { if (BuiltinID == Builtin::BI__builtin_isunordered && TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << 0 << 1 << 0 << 1; + Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 1 << TheCall->getSourceRange(); ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -9159,12 +9159,13 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || BuiltinID == Builtin::BI__builtin_isinf || BuiltinID == Builtin::BI__builtin_isinf_sign)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << 0 << 0 << 0 << 0; + Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 0 << TheCall->getSourceRange(); + if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || BuiltinID == Builtin::BI__builtin_isunordered)) - Diag(TheCall->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << 1 << 1 << 1 << 1; + Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 1 << TheCall->getSourceRange(); bool IsFPClass = NumArgs == 2; @@ -12918,15 +12919,14 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, if ((IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && FPO.getNoHonorNaNs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << 1 << 1 << 1 << 1; + Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 1 << Call->getSourceRange(); else if ((IsStdFunction(FDecl, "isinf") || (IsStdFunction(FDecl, "isfinite") || - (Call->getBuiltinCallee() == Builtin::BI__builtin_inff)) || - (FDecl->getIdentifier() && FDecl->getName() == "infinity")) && + (FDecl->getIdentifier() && FDecl->getName() == "infinity"))) && FPO.getNoHonorInfs()) - Diag(Call->getBeginLoc(), diag::warn_fast_floatingpoint_eq) - << 1 << 0 << 1 << 0; + Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 0 << Call->getSourceRange(); } // Warn when using the wrong abs() function. @@ -13897,36 +13897,6 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, CheckPPCMMAType(RetValExp->getType(), ReturnLoc); } -/// Diagnose comparison to NAN or INFINITY in fast math modes. -/// The comparison to NaN or INFINITY is always false in -/// fast modes: float evaluation will not result in inf or nan. -void Sema::CheckInfNaNFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, - BinaryOperatorKind Opcode) { - Expr *LeftExprSansParen = LHS->IgnoreParenImpCasts(); - Expr *RightExprSansParen = RHS->IgnoreParenImpCasts(); - - FPOptions FPO = LHS->getFPFeaturesInEffect(getLangOpts()); - bool NoHonorNaNs = FPO.getNoHonorNaNs(); - bool NoHonorInfs = FPO.getNoHonorInfs(); - llvm::APFloat Value(0.0); - - auto IsConstant = [&Value](Expr *E, Expr *ESansParen, ASTContext &Context) { - return !E->isValueDependent() && - ESansParen->EvaluateAsFloat(Value, Context, - Expr::SE_AllowSideEffects); - }; - - if (IsConstant(LHS, LeftExprSansParen, Context) && - ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) - Diag(Loc, diag::warn_fast_floatingpoint_eq) - << 0 << (Value.isNaN() ? 1 : 0) << 0 << (Value.isNaN() ? 1 : 0); - - if (IsConstant(RHS, RightExprSansParen, Context) && - ((NoHonorNaNs && Value.isNaN()) || (NoHonorInfs && Value.isInfinity()))) - Diag(Loc, diag::warn_fast_floatingpoint_eq) - << 0 << (Value.isNaN() ? 1 : 0) << 0 << (Value.isNaN() ? 1 : 0); -} - /// Check for comparisons of floating-point values using == and !=. Issue a /// warning if the comparison is not likely to do what the programmer intended. void Sema::CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8920137169596..f3aa1e978aa65 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13044,12 +13044,9 @@ static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS, if (Type->isAnyComplexType() && BinaryOperator::isRelationalOp(Opc)) return S.InvalidOperands(Loc, LHS, RHS); - if (Type->hasFloatingRepresentation()) { - // Check for comparisons to NAN or INFINITY in fast math mode. - S.CheckInfNaNFloatComparison(Loc, LHS.get(), RHS.get(), Opc); + if (Type->hasFloatingRepresentation()) // Check for comparisons of floating point operands using != and ==. S.CheckFloatComparison(Loc, LHS.get(), RHS.get(), Opc); - } // The result of comparisons is 'bool' in C++, 'int' in C. return S.Context.getLogicalOperationType(); diff --git a/clang/test/Sema/warn-fp-fast-compare.cpp b/clang/test/Sema/warn-fp-fast-compare.cpp deleted file mode 100644 index c6f746c3f8de1..0000000000000 --- a/clang/test/Sema/warn-fp-fast-compare.cpp +++ /dev/null @@ -1,284 +0,0 @@ -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-infs -menable-no-nans -DFAST=1 - -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -DNOFAST=1 - -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-infs -DNO_INFS=1 - -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-nans -DNO_NANS=1 - -int isunorderedf (float x, float y); -#if NOFAST -// expected-no-diagnostics -#endif -extern "C++" { -namespace std __attribute__((__visibility__("default"))) { - bool - isinf(float __x); - bool - isinf(double __x); - bool - isinf(long double __x); - bool - isnan(float __x); - bool - isnan(double __x); - bool - isnan(long double __x); -bool - isfinite(float __x); - bool - isfinite(double __x); - bool - isfinte(long double __x); - bool - isunordered(float __x, float __y); - bool - isunordered(double __x, double __y); - bool - isunordered(long double __x, long double __y); -} // namespace ) -} -#define NAN (__builtin_nanf("")) -#define INFINITY (__builtin_inff()) - -template -class numeric_limits { -public: - [[nodiscard]] static constexpr _Ty infinity() noexcept { - return _Ty(); - } -}; - -template <> -class numeric_limits { -public: - [[nodiscard]] static constexpr float infinity() noexcept { - return __builtin_huge_val(); - } -}; -template <> -class numeric_limits { -public: - [[nodiscard]] static constexpr double infinity() noexcept { - return __builtin_huge_val(); - } -}; - -int compareit(float a, float b) { - volatile int i, j, k, l, m, n, o, p; -#if FAST -// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif - i = a == INFINITY; -#if FAST -// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif - j = INFINITY == a; -#if FAST -// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif - i = a == NAN; -#if FAST -// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif - j = NAN == a; -#if FAST -// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif - j = INFINITY <= a; -#if FAST -// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif - j = INFINITY < a; -#if FAST -// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif - j = a > NAN; -#if FAST -// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{explicit comparison with nan will always return 'false' because nan will not be produced according to the currently enabled floating-point options}} -#endif - j = a >= NAN; -#if FAST -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif - k = std::isinf(a); -#if FAST -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif - l = std::isnan(a); -#if FAST -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif - o = std::isfinite(a); -#if FAST -// expected-warning@+5 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif - m = __builtin_isinf(a); -#if FAST -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif - n = __builtin_isnan(a); -#if FAST -// expected-warning@+5 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{explicit comparison with infinity will always return 'false' because infinity will not be produced according to the currently enabled floating-point options}} -#endif - p = __builtin_isfinite(a); - - // These should NOT warn, since they are not comparing with NaN or infinity. - j = a > 1.1; - j = b < 1.1; - j = a >= 1.1; - j = b <= 1.1; - j = isunorderedf(a, b); - -#if FAST -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif - j = isunorderedf(a, NAN); -#if FAST -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif - j = isunorderedf(a, INFINITY); -#if FAST -// expected-warning@+11 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif - i = std::isunordered(a, NAN); -#if FAST -// expected-warning@+11 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of nan as a function argument will not always be interpreted as such because nan will not be produced according to the currently enabled floating-point options}} -#endif - i = std::isunordered(a, INFINITY); -#if FAST -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif - double y = i * numeric_limits::infinity(); - -#if FAST -// expected-warning@+5 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity as a function argument will not always be interpreted as such because infinity will not be produced according to the currently enabled floating-point options}} -#endif - j = numeric_limits::infinity(); - return 0; - -} diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp new file mode 100644 index 0000000000000..b23bceeacc1d9 --- /dev/null +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -0,0 +1,237 @@ +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans -DFAST=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -DNOFAST=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -DNO_INFS=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-nans -DNO_NANS=1 + +int isunorderedf (float x, float y); +#if NOFAST +// expected-no-diagnostics +#endif +extern "C++" { +namespace std __attribute__((__visibility__("default"))) { + bool + isinf(float __x); + bool + isinf(double __x); + bool + isinf(long double __x); + bool + isnan(float __x); + bool + isnan(double __x); + bool + isnan(long double __x); +bool + isfinite(float __x); + bool + isfinite(double __x); + bool + isfinte(long double __x); + bool + isunordered(float __x, float __y); + bool + isunordered(double __x, double __y); + bool + isunordered(long double __x, long double __y); +} // namespace ) +} + +#define NAN (__builtin_nanf("")) +#define INFINITY (__builtin_inff()) + +template +class numeric_limits { +public: + [[nodiscard]] static constexpr _Ty infinity() noexcept { + return _Ty(); + } +}; + +template <> +class numeric_limits { +public: + [[nodiscard]] static constexpr float infinity() noexcept { + return __builtin_huge_val(); + } +}; +template <> +class numeric_limits { +public: + [[nodiscard]] static constexpr double infinity() noexcept { + return __builtin_huge_val(); + } +}; + +int compareit(float a, float b) { + volatile int i, j, k, l, m, n, o, p; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + i = a == INFINITY; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point option}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = INFINITY == a; +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + i = a == NAN; +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + j = NAN == a; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = INFINITY <= a; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = INFINITY < a; +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + j = a > NAN; +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + j = a >= NAN; +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + k = std::isinf(a); +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + l = std::isnan(a); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + o = std::isfinite(a); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + m = __builtin_isinf(a); +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + n = __builtin_isnan(a); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + p = __builtin_isfinite(a); + + // These should NOT warn, since they are not comparing with NaN or infinity. + j = a > 1.1; + j = b < 1.1; + j = a >= 1.1; + j = b <= 1.1; + j = isunorderedf(a, b); + +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + j = isunorderedf(a, NAN); +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = isunorderedf(a, INFINITY); +#if FAST +// expected-warning@+11 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + i = std::isunordered(a, NAN); +#if FAST +// expected-warning@+11 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point option}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + i = std::isunordered(a, INFINITY); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + double y = i * numeric_limits::infinity(); + +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + j = numeric_limits::infinity(); + return 0; + +} diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp new file mode 100644 index 0000000000000..085de5b92f84c --- /dev/null +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -0,0 +1,240 @@ +// Use of NAN macro will trigger a warning "infinity defined in macro" because +// on Windows the NAN macro is defined using INFINITY. See below. + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans -DFAST=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -DNOFAST=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -DNO_INFS=1 + +// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-nans -DNO_NANS=1 + +int isunorderedf (float x, float y); +#if NOFAST +// expected-no-diagnostics +#endif +extern "C++" { +namespace std __attribute__((__visibility__("default"))) { + bool + isinf(float __x); + bool + isinf(double __x); + bool + isinf(long double __x); + bool + isnan(float __x); + bool + isnan(double __x); + bool + isnan(long double __x); +bool + isfinite(float __x); + bool + isfinite(double __x); + bool + isfinte(long double __x); + bool + isunordered(float __x, float __y); + bool + isunordered(double __x, double __y); + bool + isunordered(long double __x, long double __y); +} // namespace ) +} + +#define INFINITY ((float)(1e+300 * 1e+300)) +#define NAN (-(float)(INFINITY * 0.0F)) + +template +class numeric_limits { +public: + [[nodiscard]] static constexpr _Ty infinity() noexcept { + return _Ty(); + } +}; + +template <> +class numeric_limits { +public: + [[nodiscard]] static constexpr float infinity() noexcept { + return __builtin_huge_val(); + } +}; +template <> +class numeric_limits { +public: + [[nodiscard]] static constexpr double infinity() noexcept { + return __builtin_huge_val(); + } +}; + +int compareit(float a, float b) { + volatile int i, j, k, l, m, n, o, p; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + i = a == INFINITY; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = INFINITY == a; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + i = a == NAN; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = NAN == a; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = INFINITY <= a; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = INFINITY < a; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = a > NAN; +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = a >= NAN; +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + k = std::isinf(a); +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + l = std::isnan(a); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + o = std::isfinite(a); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + m = __builtin_isinf(a); +#if FAST +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + n = __builtin_isnan(a); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + p = __builtin_isfinite(a); + + // These should NOT warn, since they are not comparing with NaN or infinity. + j = a > 1.1; + j = b < 1.1; + j = a >= 1.1; + j = b <= 1.1; + j = isunorderedf(a, b); + +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = isunorderedf(a, NAN); +#if FAST +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif + j = isunorderedf(a, INFINITY); +#if FAST +// expected-warning@+11 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + i = std::isunordered(a, NAN); +#if FAST +// expected-warning@+11 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_NANS +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif + i = std::isunordered(a, INFINITY); +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + double y = i * numeric_limits::infinity(); + +#if FAST +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +#endif + j = numeric_limits::infinity(); + return 0; + +} From 71431deb512fab0cb0fe7454e371a12d204f0699 Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Thu, 18 Jan 2024 06:39:49 -0800 Subject: [PATCH 07/10] Fixed the diagnostics and RN. --- clang/docs/ReleaseNotes.rst | 9 +- .../clang/Basic/DiagnosticCommonKinds.td | 7 +- .../clang/Basic/DiagnosticSemaKinds.td | 4 - clang/lib/Lex/Preprocessor.cpp | 2 +- clang/lib/Sema/SemaChecking.cpp | 10 +-- clang/lib/Sema/SemaExpr.cpp | 2 +- .../Sema/warn-infinity-nan-disabled-lnx.cpp | 88 +++++++++---------- .../Sema/warn-infinity-nan-disabled-win.cpp | 88 +++++++++---------- 8 files changed, 104 insertions(+), 106 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b2b32821524d1..acaf5996ddcf1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -558,10 +558,11 @@ Improvements to Clang's diagnostics - Clang now diagnoses narrowing conversions involving const references. (`#63151: `_). - Clang now diagnoses unexpanded packs within the template argument lists of function template specializations. -- Clang's ``-Wtautological-logical-constant-compare`` flag now diagnoses - when ``INFINITY`` or ``NAN`` are used in arithmetic operations or function - arguments in floating-points mode where ``INFINITY`` or ``NAN`` don't have the - expected values. +- The warning `-Wnan-and-infinity-disabled` is now emitted when ``INFINITY`` + or ``NAN`` are used in arithmetic operations or function arguments in + floating-point mode where ``INFINITY`` or ``NAN`` don't have the expected + values. + - Clang now diagnoses attempts to bind a bitfield to an NTTP of a reference type as erroneous converted constant expression and not as a reference to subobject. diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 8c096568ebd45..93d65504a7b12 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -69,10 +69,11 @@ def warn_pragma_debug_missing_argument : Warning< "missing argument to debug command '%0'">, InGroup; def warn_pragma_debug_unexpected_argument : Warning< "unexpected argument to debug command">, InGroup; -def warn_infinity_defined_in_macro : Warning< - "infinity defined via a macro will result in an undefined behavior " + +def warn_fp_nan_inf_when_disabled : Warning< + "use of %select{infinity|NaN}0 %select{|via a macro}1 results in an undefined behavior " "due to the currently enabled floating-point options">, - InGroup>; + InGroup>; } // Parse && Sema diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 070986aa45313..1a79892e40030 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6784,10 +6784,6 @@ def warn_pointer_sub_null_ptr : Warning< def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; -def warn_fp_nan_inf_when_disabled : Warning< - "use of %select{infinity|NaN}0 results in undefined behavior due to the " - "currently enabled floating-point options">, - InGroup>; def err_setting_eval_method_used_in_unsafe_context : Error < "%select{'#pragma clang fp eval_method'|option 'ffp-eval-method'}0 cannot be used with " diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index da8e57ff08402..b821e947c36a5 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -1459,7 +1459,7 @@ void Preprocessor::emitRestrictExpansionWarning(const Token &Identifier) const { void Preprocessor::emitRestrictInfNaNWarning(const Token &Identifier) const { if (getLangOpts().NoHonorInfs) - Diag(Identifier, diag::warn_infinity_defined_in_macro); + Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << 0 << 1; } void Preprocessor::emitFinalMacroWarning(const Token &Identifier, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 6195d0b361a78..a35ee7af0d010 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9114,7 +9114,7 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { if (BuiltinID == Builtin::BI__builtin_isunordered && TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 1 << TheCall->getSourceRange(); + << 1 << 0 << TheCall->getSourceRange(); ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -9160,12 +9160,12 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, BuiltinID == Builtin::BI__builtin_isinf || BuiltinID == Builtin::BI__builtin_isinf_sign)) Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 0 << TheCall->getSourceRange(); + << 0 << 0 << TheCall->getSourceRange(); if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || BuiltinID == Builtin::BI__builtin_isunordered)) Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 1 << TheCall->getSourceRange(); + << 1 << 0 << TheCall->getSourceRange(); bool IsFPClass = NumArgs == 2; @@ -12920,13 +12920,13 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, (Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) && FPO.getNoHonorNaNs()) Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 1 << Call->getSourceRange(); + << 1 << 0 << Call->getSourceRange(); else if ((IsStdFunction(FDecl, "isinf") || (IsStdFunction(FDecl, "isfinite") || (FDecl->getIdentifier() && FDecl->getName() == "infinity"))) && FPO.getNoHonorInfs()) Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 0 << Call->getSourceRange(); + << 0 << 0 << Call->getSourceRange(); } // Warn when using the wrong abs() function. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f3aa1e978aa65..2f48ea237cdfa 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13044,8 +13044,8 @@ static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS, if (Type->isAnyComplexType() && BinaryOperator::isRelationalOp(Opc)) return S.InvalidOperands(Loc, LHS, RHS); + // Check for comparisons of floating point operands using != and ==. if (Type->hasFloatingRepresentation()) - // Check for comparisons of floating point operands using != and ==. S.CheckFloatComparison(Loc, LHS.get(), RHS.get(), Opc); // The result of comparisons is 'bool' in C++, 'int' in C. diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp index b23bceeacc1d9..8719161083ba3 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -72,101 +72,101 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif i = a == INFINITY; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point option}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY == a; #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif i = a == NAN; #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif j = NAN == a; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY < a; #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif j = a > NAN; #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif k = std::isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif n = __builtin_isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif p = __builtin_isfinite(a); @@ -178,58 +178,58 @@ int compareit(float a, float b) { j = isunorderedf(a, b); #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, NAN); #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+11 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+8 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+11 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point option}} +// expected-warning@+11 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+8 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, INFINITY); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif double y = i * numeric_limits::infinity(); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif j = numeric_limits::infinity(); return 0; diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp index 085de5b92f84c..82d2a6c9cadb5 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -75,101 +75,101 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif i = a == INFINITY; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY == a; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif i = a == NAN; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = NAN == a; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY < a; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = a > NAN; #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif k = std::isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif n = __builtin_isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif p = __builtin_isfinite(a); @@ -181,58 +181,58 @@ int compareit(float a, float b) { j = isunorderedf(a, b); #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, NAN); #if FAST -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+11 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+8 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+11 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+8 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{infinity defined via a macro will result in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, INFINITY); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif double y = i * numeric_limits::infinity(); #if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} #endif j = numeric_limits::infinity(); return 0; From c8743354e13185a42c6cab60b7962946a802c86c Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Thu, 18 Jan 2024 08:26:23 -0800 Subject: [PATCH 08/10] Fixed diag's comment and added NAN to the macro testing. --- .../clang/Basic/DiagnosticCommonKinds.td | 2 +- clang/include/clang/Lex/Preprocessor.h | 3 +- .../Sema/warn-infinity-nan-disabled-lnx.cpp | 124 +++++++++++------- .../Sema/warn-infinity-nan-disabled-win.cpp | 124 +++++++++++------- 4 files changed, 163 insertions(+), 90 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 93d65504a7b12..9868557bead4f 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -71,7 +71,7 @@ def warn_pragma_debug_unexpected_argument : Warning< "unexpected argument to debug command">, InGroup; def warn_fp_nan_inf_when_disabled : Warning< - "use of %select{infinity|NaN}0 %select{|via a macro}1 results in an undefined behavior " + "use of %select{infinity|NaN}0%select{| via a macro}1 results in undefined behavior " "due to the currently enabled floating-point options">, InGroup>; } diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4ad034c02d6b1..7286d49bd8d80 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2836,7 +2836,8 @@ class Preprocessor { !SourceMgr.isInMainFile(Identifier.getLocation())) emitRestrictExpansionWarning(Identifier); - if (Identifier.getIdentifierInfo()->getName() == "INFINITY") + if (Identifier.getIdentifierInfo()->getName() == "INFINITY" || + Identifier.getIdentifierInfo()->getName() == "NAN") emitRestrictInfNaNWarning(Identifier); } diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp index 8719161083ba3..a4b40d14d353d 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -72,101 +72,125 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif i = a == INFINITY; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY == a; #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif i = a == NAN; #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif j = NAN == a; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY < a; #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif j = a > NAN; #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif k = std::isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif n = __builtin_isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif p = __builtin_isfinite(a); @@ -178,58 +202,70 @@ int compareit(float a, float b) { j = isunorderedf(a, b); #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, NAN); #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+11 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+17 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+14 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+11 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, INFINITY); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif double y = i * numeric_limits::infinity(); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif j = numeric_limits::infinity(); return 0; diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp index 82d2a6c9cadb5..82a55872df8a8 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -75,101 +75,125 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif i = a == INFINITY; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY == a; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif i = a == NAN; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = NAN == a; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY <= a; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = INFINITY < a; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = a > NAN; #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = a >= NAN; #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif k = std::isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif l = std::isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif o = std::isfinite(a); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif m = __builtin_isinf(a); #if FAST -// expected-warning@+5 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif n = __builtin_isnan(a); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif p = __builtin_isfinite(a); @@ -181,58 +205,70 @@ int compareit(float a, float b) { j = isunorderedf(a, b); #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, NAN); #if FAST -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif j = isunorderedf(a, INFINITY); #if FAST -// expected-warning@+11 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+17 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if FAST +// expected-warning@+14 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} +#endif +#if NO_INFS +// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, NAN); #if FAST -// expected-warning@+11 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if FAST -// expected-warning@+8 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_NANS -// expected-warning@+2 {{use of NaN results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} #endif i = std::isunordered(a, INFINITY); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif double y = i * numeric_limits::infinity(); #if FAST -// expected-warning@+5 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif #if NO_INFS -// expected-warning@+2 {{use of infinity results in an undefined behavior due to the currently enabled floating-point options}} +// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} #endif j = numeric_limits::infinity(); return 0; From c0bd9e53bdb2b186ce0bf841eb37d3de4c74324a Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Fri, 19 Jan 2024 08:14:16 -0800 Subject: [PATCH 09/10] Fixed LIT tests, RN and warning message. --- clang/docs/ReleaseNotes.rst | 2 +- .../clang/Basic/DiagnosticCommonKinds.td | 4 +- clang/include/clang/Lex/Preprocessor.h | 12 +- clang/lib/Lex/Preprocessor.cpp | 6 +- .../Sema/warn-infinity-nan-disabled-lnx.cpp | 255 ++++++------------ .../Sema/warn-infinity-nan-disabled-win.cpp | 255 ++++++------------ 6 files changed, 174 insertions(+), 360 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index acaf5996ddcf1..07407ff3a1713 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -558,7 +558,7 @@ Improvements to Clang's diagnostics - Clang now diagnoses narrowing conversions involving const references. (`#63151: `_). - Clang now diagnoses unexpanded packs within the template argument lists of function template specializations. -- The warning `-Wnan-and-infinity-disabled` is now emitted when ``INFINITY`` +- The warning `-Wnan-infinity-disabled` is now emitted when ``INFINITY`` or ``NAN`` are used in arithmetic operations or function arguments in floating-point mode where ``INFINITY`` or ``NAN`` don't have the expected values. diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 9868557bead4f..80ee94b84263a 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -71,9 +71,9 @@ def warn_pragma_debug_unexpected_argument : Warning< "unexpected argument to debug command">, InGroup; def warn_fp_nan_inf_when_disabled : Warning< - "use of %select{infinity|NaN}0%select{| via a macro}1 results in undefined behavior " + "use of %select{infinity|NaN}0%select{| via a macro}1 is undefined behavior " "due to the currently enabled floating-point options">, - InGroup>; + InGroup>; } // Parse && Sema diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 7286d49bd8d80..fed3c1b770383 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2836,9 +2836,12 @@ class Preprocessor { !SourceMgr.isInMainFile(Identifier.getLocation())) emitRestrictExpansionWarning(Identifier); - if (Identifier.getIdentifierInfo()->getName() == "INFINITY" || - Identifier.getIdentifierInfo()->getName() == "NAN") - emitRestrictInfNaNWarning(Identifier); + if (Identifier.getIdentifierInfo()->getName() == "INFINITY") + if (getLangOpts().NoHonorInfs) + emitRestrictInfNaNWarning(Identifier, 0); + if (Identifier.getIdentifierInfo()->getName() == "NAN") + if (getLangOpts().NoHonorNaNs) + emitRestrictInfNaNWarning(Identifier, 1); } static void processPathForFileMacro(SmallVectorImpl &Path, @@ -2854,7 +2857,8 @@ class Preprocessor { void emitMacroDeprecationWarning(const Token &Identifier) const; void emitRestrictExpansionWarning(const Token &Identifier) const; void emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const; - void emitRestrictInfNaNWarning(const Token &Identifier) const; + void emitRestrictInfNaNWarning(const Token &Identifier, + unsigned DiagSelection) const; /// This boolean state keeps track if the current scanned token (by this PP) /// is in an "-Wunsafe-buffer-usage" opt-out region. Assuming PP scans a diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index b821e947c36a5..7fdb5d4c0d7b8 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -1457,9 +1457,9 @@ void Preprocessor::emitRestrictExpansionWarning(const Token &Identifier) const { Diag(Info.Location, diag::note_pp_macro_annotation) << 1; } -void Preprocessor::emitRestrictInfNaNWarning(const Token &Identifier) const { - if (getLangOpts().NoHonorInfs) - Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << 0 << 1; +void Preprocessor::emitRestrictInfNaNWarning(const Token &Identifier, + unsigned DiagSelection) const { + Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << DiagSelection << 1; } void Preprocessor::emitFinalMacroWarning(const Token &Identifier, diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp index a4b40d14d353d..ef8d0cac02f3b 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -1,14 +1,14 @@ -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-infs -menable-no-nans -DFAST=1 +// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans // RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ // RUN: -DNOFAST=1 -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-infs -DNO_INFS=1 +// RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-nans -DNO_NANS=1 +// RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-nans int isunorderedf (float x, float y); #if NOFAST @@ -71,202 +71,107 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} i = a == INFINITY; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY == a; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = a == NAN; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = NAN == a; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY <= a; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY < a; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} j = a > NAN; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = a >= NAN; -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} k = std::isinf(a); -#if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point option}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} l = std::isnan(a); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} o = std::isfinite(a); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} m = __builtin_isinf(a); -#if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} n = __builtin_isnan(a); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} p = __builtin_isfinite(a); - // These should NOT warn, since they are not comparing with NaN or infinity. + // These should NOT warn, since they are not using NaN or infinity. j = a > 1.1; j = b < 1.1; j = a >= 1.1; j = b <= 1.1; j = isunorderedf(a, b); -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif +// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} j = isunorderedf(a, NAN); -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = isunorderedf(a, INFINITY); -#if FAST -// expected-warning@+17 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+14 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+11 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+6 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+5 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = std::isunordered(a, NAN); -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = std::isunordered(a, INFINITY); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} double y = i * numeric_limits::infinity(); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} j = numeric_limits::infinity(); return 0; diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp index 82a55872df8a8..5bdca3e626c44 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -1,17 +1,17 @@ // Use of NAN macro will trigger a warning "infinity defined in macro" because // on Windows the NAN macro is defined using INFINITY. See below. -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-infs -menable-no-nans -DFAST=1 +// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -menable-no-nans // RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ // RUN: -DNOFAST=1 -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-infs -DNO_INFS=1 +// RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-infs -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -menable-no-nans -DNO_NANS=1 +// RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \ +// RUN: -menable-no-nans int isunorderedf (float x, float y); #if NOFAST @@ -74,202 +74,107 @@ class numeric_limits { int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} i = a == INFINITY; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY == a; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} i = a == NAN; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = NAN == a; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY <= a; -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = INFINITY < a; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = a > NAN; -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = a >= NAN; -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} k = std::isinf(a); -#if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} l = std::isnan(a); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} o = std::isfinite(a); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} m = __builtin_isinf(a); -#if FAST -// expected-warning@+5 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} n = __builtin_isnan(a); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} p = __builtin_isfinite(a); - // These should NOT warn, since they are not comparing with NaN or infinity. + // These should NOT warn, since they are not using NaN or infinity. j = a > 1.1; j = b < 1.1; j = a >= 1.1; j = b <= 1.1; j = isunorderedf(a, b); -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif +// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point option}} +// no-inf-no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} j = isunorderedf(a, NAN); -#if FAST -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} j = isunorderedf(a, INFINITY); -#if FAST -// expected-warning@+17 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+14 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+8 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+6 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+5 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = std::isunordered(a, NAN); -#if FAST -// expected-warning@+11 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if FAST -// expected-warning@+8 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+5 {{use of infinity via a macro results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_NANS -// expected-warning@+2 {{use of NaN results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} +// no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} i = std::isunordered(a, INFINITY); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif + +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} double y = i * numeric_limits::infinity(); -#if FAST -// expected-warning@+5 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif -#if NO_INFS -// expected-warning@+2 {{use of infinity results in undefined behavior due to the currently enabled floating-point options}} -#endif +// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} +// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} j = numeric_limits::infinity(); return 0; From 3506625a7295b904ba4d75195aa0f5d61c6bf69b Mon Sep 17 00:00:00 2001 From: Ammarguellat Date: Fri, 19 Jan 2024 09:45:33 -0800 Subject: [PATCH 10/10] Fix LIT tests. --- clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp | 8 +++----- clang/test/Sema/warn-infinity-nan-disabled-win.cpp | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp index ef8d0cac02f3b..8a610fa0e737e 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -1,8 +1,7 @@ // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan -triple powerpc64le-unknown-unknown %s \ // RUN: -menable-no-infs -menable-no-nans -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -DNOFAST=1 +// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown %s // RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \ // RUN: -menable-no-infs @@ -10,10 +9,9 @@ // RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \ // RUN: -menable-no-nans +// no-fast-no-diagnostics + int isunorderedf (float x, float y); -#if NOFAST -// expected-no-diagnostics -#endif extern "C++" { namespace std __attribute__((__visibility__("default"))) { bool diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp index 5bdca3e626c44..19a575386e329 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -4,8 +4,7 @@ // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan -triple powerpc64le-unknown-unknown %s \ // RUN: -menable-no-infs -menable-no-nans -// RUN: %clang_cc1 -x c++ -verify -triple powerpc64le-unknown-unknown %s \ -// RUN: -DNOFAST=1 +// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown %s // RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \ // RUN: -menable-no-infs @@ -13,10 +12,9 @@ // RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \ // RUN: -menable-no-nans +// no-fast-no-diagnostics + int isunorderedf (float x, float y); -#if NOFAST -// expected-no-diagnostics -#endif extern "C++" { namespace std __attribute__((__visibility__("default"))) { bool