Skip to content

Commit e5992b6

Browse files
authored
[Clang] Fix warning for non std functions with name infinity (#123417)
Fix reporting diagnostic for non std functions that has the name `infinity` Fixes: #123231
1 parent 28ae363 commit e5992b6

File tree

4 files changed

+111
-23
lines changed

4 files changed

+111
-23
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,8 @@ Improvements to Clang's diagnostics
798798
}
799799
- Diagnose invalid declarators in the declaration of constructors and destructors (#GH121706).
800800

801+
- Fix false positives warning for non-std functions with name `infinity` (#123231).
802+
801803
Improvements to Clang's time-trace
802804
----------------------------------
803805

clang/lib/Sema/SemaChecking.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8454,26 +8454,43 @@ static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check) {
84548454
llvm_unreachable("unknown MathCheck");
84558455
}
84568456

8457+
static bool IsInfinityFunction(const FunctionDecl *FDecl) {
8458+
if (FDecl->getName() != "infinity")
8459+
return false;
8460+
8461+
if (const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
8462+
const CXXRecordDecl *RDecl = MDecl->getParent();
8463+
if (RDecl->getName() != "numeric_limits")
8464+
return false;
8465+
8466+
if (const NamespaceDecl *NSDecl =
8467+
dyn_cast<NamespaceDecl>(RDecl->getDeclContext()))
8468+
return NSDecl->isStdNamespace();
8469+
}
8470+
8471+
return false;
8472+
}
8473+
84578474
void Sema::CheckInfNaNFunction(const CallExpr *Call,
84588475
const FunctionDecl *FDecl) {
8476+
if (!FDecl->getIdentifier())
8477+
return;
8478+
84598479
FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts());
8460-
bool HasIdentifier = FDecl->getIdentifier() != nullptr;
8461-
bool IsNaNOrIsUnordered =
8462-
IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered");
8463-
bool IsSpecialNaN =
8464-
HasIdentifier && IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN);
8465-
if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) {
8480+
if (FPO.getNoHonorNaNs() &&
8481+
(IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") ||
8482+
IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN))) {
84668483
Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
84678484
<< 1 << 0 << Call->getSourceRange();
8468-
} else {
8469-
bool IsInfOrIsFinite =
8470-
IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite");
8471-
bool IsInfinityOrIsSpecialInf =
8472-
HasIdentifier && ((FDecl->getName() == "infinity") ||
8473-
IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf));
8474-
if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs())
8475-
Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8476-
<< 0 << 0 << Call->getSourceRange();
8485+
return;
8486+
}
8487+
8488+
if (FPO.getNoHonorInfs() &&
8489+
(IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite") ||
8490+
IsInfinityFunction(FDecl) ||
8491+
IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf))) {
8492+
Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8493+
<< 0 << 0 << Call->getSourceRange();
84778494
}
84788495
}
84798496

clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,48 @@ namespace std __attribute__((__visibility__("default"))) {
4545
isnan(double __x);
4646
bool
4747
isnan(long double __x);
48-
bool
48+
bool
4949
isfinite(float __x);
5050
bool
5151
isfinite(double __x);
5252
bool
5353
isfinte(long double __x);
54-
bool
54+
bool
5555
isunordered(float __x, float __y);
5656
bool
5757
isunordered(double __x, double __y);
5858
bool
5959
isunordered(long double __x, long double __y);
60+
61+
template <class _Ty>
62+
class numeric_limits {
63+
public:
64+
[[nodiscard]] static constexpr _Ty infinity() noexcept {
65+
return _Ty();
66+
}
67+
};
6068
} // namespace )
6169
}
6270

6371
#define NAN (__builtin_nanf(""))
6472
#define INFINITY (__builtin_inff())
6573

74+
template <>
75+
class std::numeric_limits<float> {
76+
public:
77+
[[nodiscard]] static constexpr float infinity() noexcept {
78+
return __builtin_huge_val();
79+
}
80+
};
81+
82+
template <>
83+
class std::numeric_limits<double> {
84+
public:
85+
[[nodiscard]] static constexpr double infinity() noexcept {
86+
return __builtin_huge_val();
87+
}
88+
};
89+
6690
template <class _Ty>
6791
class numeric_limits {
6892
public:
@@ -78,6 +102,7 @@ class numeric_limits<float> {
78102
return __builtin_huge_val();
79103
}
80104
};
105+
81106
template <>
82107
class numeric_limits<double> {
83108
public:
@@ -86,6 +111,8 @@ class numeric_limits<double> {
86111
}
87112
};
88113

114+
double infinity() { return 0; }
115+
89116
int compareit(float a, float b) {
90117
volatile int i, j, k, l, m, n, o, p;
91118
// no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
@@ -225,11 +252,18 @@ int compareit(float a, float b) {
225252

226253
// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
227254
// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
228-
double y = i * numeric_limits<double>::infinity();
255+
double y = i * std::numeric_limits<double>::infinity();
256+
257+
y = i * numeric_limits<double>::infinity(); // expected-no-diagnostics
229258

230259
// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
231260
// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
232-
j = numeric_limits<float>::infinity();
261+
j = std::numeric_limits<float>::infinity();
262+
263+
j = numeric_limits<float>::infinity(); // expected-no-diagnostics
264+
265+
y = infinity(); // expected-no-diagnostics
266+
233267
return 0;
234268

235269
}

clang/test/Sema/warn-infinity-nan-disabled-win.cpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,49 @@ namespace std __attribute__((__visibility__("default"))) {
4848
isnan(double __x);
4949
bool
5050
isnan(long double __x);
51-
bool
51+
bool
5252
isfinite(float __x);
5353
bool
5454
isfinite(double __x);
5555
bool
5656
isfinte(long double __x);
57-
bool
57+
bool
5858
isunordered(float __x, float __y);
5959
bool
6060
isunordered(double __x, double __y);
6161
bool
6262
isunordered(long double __x, long double __y);
63+
64+
template <class _Ty>
65+
class numeric_limits {
66+
public:
67+
[[nodiscard]] static constexpr _Ty infinity() noexcept {
68+
return _Ty();
69+
}
70+
};
71+
6372
} // namespace )
6473
}
6574

6675
#define INFINITY ((float)(1e+300 * 1e+300))
6776
#define NAN (-(float)(INFINITY * 0.0F))
6877

78+
template <>
79+
class std::numeric_limits<float> {
80+
public:
81+
[[nodiscard]] static constexpr float infinity() noexcept {
82+
return __builtin_huge_val();
83+
}
84+
};
85+
86+
template <>
87+
class std::numeric_limits<double> {
88+
public:
89+
[[nodiscard]] static constexpr double infinity() noexcept {
90+
return __builtin_huge_val();
91+
}
92+
};
93+
6994
template <class _Ty>
7095
class numeric_limits {
7196
public:
@@ -81,6 +106,7 @@ class numeric_limits<float> {
81106
return __builtin_huge_val();
82107
}
83108
};
109+
84110
template <>
85111
class numeric_limits<double> {
86112
public:
@@ -89,6 +115,8 @@ class numeric_limits<double> {
89115
}
90116
};
91117

118+
double infinity() { return 0; }
119+
92120
int compareit(float a, float b) {
93121
volatile int i, j, k, l, m, n, o, p;
94122
// no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}}
@@ -216,11 +244,18 @@ int compareit(float a, float b) {
216244

217245
// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
218246
// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
219-
double y = i * numeric_limits<double>::infinity();
247+
double y = i * std::numeric_limits<double>::infinity();
248+
249+
y = i * numeric_limits<double>::infinity(); // expected-no-diagnostics
220250

221251
// no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
222252
// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
223-
j = numeric_limits<float>::infinity();
253+
j = std::numeric_limits<float>::infinity();
254+
255+
j = numeric_limits<float>::infinity(); // expected-no-diagnostics
256+
257+
y = infinity(); // expected-no-diagnostics
258+
224259
return 0;
225260

226261
}

0 commit comments

Comments
 (0)