Skip to content

Commit dd7fed9

Browse files
zahiraamtstellar
authored andcommitted
[CLANG] Fix INF/NAN warning. (llvm#80290)
In llvm#76873 a warning was added when the macros INFINITY and NAN are used in binary expressions when -menable-no-nans or -menable-no-infs are used. If the user uses an option that nullifies these two options, the warning will still be generated. This patch adds an additional information to the warning comment to let the user know about this. It also suppresses the warning when #ifdef INFINITY, #ifdef NAN, #ifdef NAN or #ifndef NAN are used in the code. (cherry picked from commit 62c352e)
1 parent d5af513 commit dd7fed9

7 files changed

+126
-22
lines changed

clang/include/clang/Basic/DiagnosticCommonKinds.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def warn_pragma_debug_unexpected_argument : Warning<
7373
def warn_fp_nan_inf_when_disabled : Warning<
7474
"use of %select{infinity|NaN}0%select{| via a macro}1 is undefined behavior "
7575
"due to the currently enabled floating-point options">,
76-
InGroup<DiagGroup<"nan-infinity-disabled">>;
76+
InGroup<DiagGroup<"nan-infinity-disabled", [], NanInfDisabledDocs>>;
7777
}
7878

7979
// Parse && Sema

clang/include/clang/Basic/DiagnosticDocs.td

+9
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,12 @@ program by treating all string literals as having type ``const char *``
8787
instead of ``char *``. This can cause unexpected behaviors with type-sensitive
8888
constructs like ``_Generic``.
8989
}];
90+
91+
defvar NanInfDisabledDocs = [{
92+
This warning is enabled when source code using the macros ``INFINITY`` or ``NAN``
93+
is compiled with floating-point options preventing these two values. This can
94+
lead to undefined behavior. Check the order of command line arguments that modify
95+
this behavior, such as ``-ffast-math``, ``-fhonor-infinities``, and
96+
``-fhonor-nans`` (etc), as well as ``#pragma`` directives if this diagnostic is
97+
generated unexpectedly.
98+
}];

clang/include/clang/Lex/Preprocessor.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -2828,7 +2828,8 @@ class Preprocessor {
28282828
return AnnotationInfos.find(II)->second;
28292829
}
28302830

2831-
void emitMacroExpansionWarnings(const Token &Identifier) const {
2831+
void emitMacroExpansionWarnings(const Token &Identifier,
2832+
bool IsIfnDef = false) const {
28322833
IdentifierInfo *Info = Identifier.getIdentifierInfo();
28332834
if (Info->isDeprecatedMacro())
28342835
emitMacroDeprecationWarning(Identifier);
@@ -2837,12 +2838,12 @@ class Preprocessor {
28372838
!SourceMgr.isInMainFile(Identifier.getLocation()))
28382839
emitRestrictExpansionWarning(Identifier);
28392840

2840-
if (Info->getName() == "INFINITY")
2841-
if (getLangOpts().NoHonorInfs)
2841+
if (!IsIfnDef) {
2842+
if (Info->getName() == "INFINITY" && getLangOpts().NoHonorInfs)
28422843
emitRestrictInfNaNWarning(Identifier, 0);
2843-
if (Info->getName() == "NAN")
2844-
if (getLangOpts().NoHonorNaNs)
2844+
if (Info->getName() == "NAN" && getLangOpts().NoHonorNaNs)
28452845
emitRestrictInfNaNWarning(Identifier, 1);
2846+
}
28462847
}
28472848

28482849
static void processPathForFileMacro(SmallVectorImpl<char> &Path,

clang/lib/Lex/PPDirectives.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3288,7 +3288,7 @@ void Preprocessor::HandleIfdefDirective(Token &Result,
32883288
return;
32893289
}
32903290

3291-
emitMacroExpansionWarnings(MacroNameTok);
3291+
emitMacroExpansionWarnings(MacroNameTok, /*IsIfnDef=*/true);
32923292

32933293
// Check to see if this is the last token on the #if[n]def line.
32943294
CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef");

clang/lib/Lex/PPExpressions.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
133133
Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
134134
DT.IncludedUndefinedIds = !Macro;
135135

136-
PP.emitMacroExpansionWarnings(PeekTok);
136+
PP.emitMacroExpansionWarnings(
137+
PeekTok,
138+
(II->getName() == "INFINITY" || II->getName() == "NAN") ? true : false);
137139

138140
// If there is a macro, mark it used.
139141
if (Result.Val != 0 && ValueLive)

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

+53-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
1-
// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan -triple powerpc64le-unknown-unknown %s \
2-
// RUN: -menable-no-infs -menable-no-nans
1+
// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \
2+
// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \
3+
// RUN: -menable-no-nans -std=c++23
34

4-
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown %s
5+
// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \
6+
// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \
7+
// RUN: -menable-no-nans -funsafe-math-optimizations -std=c++23
8+
9+
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \
10+
// RUN: %s -std=c++23
11+
12+
// RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \
13+
// RUN: -menable-no-infs -std=c++23
514

615
// RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \
7-
// RUN: -menable-no-infs
16+
// RUN: -menable-no-infs -funsafe-math-optimizations -std=c++23
17+
18+
// RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \
19+
// RUN: -menable-no-nans -std=c++23
820

921
// RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \
10-
// RUN: -menable-no-nans
22+
// RUN: -funsafe-math-optimizations -menable-no-nans -std=c++23
23+
24+
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \
25+
// RUN: %s -Wno-nan-infinity-disabled -menable-no-infs -std=c++23
26+
27+
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \
28+
// RUN: %s -Wno-nan-infinity-disabled -menable-no-nans -std=c++23
1129

1230
// no-fast-no-diagnostics
1331

@@ -133,13 +151,41 @@ int compareit(float a, float b) {
133151
// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
134152
p = __builtin_isfinite(a);
135153

136-
// These should NOT warn, since they are not using NaN or infinity.
154+
// These should NOT warn, since they are not using NaN or infinity.
137155
j = a > 1.1;
138156
j = b < 1.1;
139157
j = a >= 1.1;
140158
j = b <= 1.1;
141159
j = isunorderedf(a, b);
142160

161+
#ifndef INFINITY
162+
j = a;
163+
#endif
164+
#ifndef NAN
165+
j = b;
166+
#endif
167+
#ifdef INFINITY
168+
j = a;
169+
#endif
170+
#ifdef NAN
171+
j = b;
172+
#endif
173+
#if defined(INFINITY)
174+
j = a;
175+
#elifndef(INFINITY)
176+
j = b;
177+
#endif
178+
#if defined(INFINITY)
179+
j = a;
180+
#elifndef(NAN)
181+
j = b;
182+
#endif
183+
#if defined(NAN)
184+
j = a;
185+
#elifndef(INFINITY)
186+
j = b;
187+
#endif
188+
143189
// no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}}
144190
// no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}}
145191
// no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}}
@@ -173,4 +219,4 @@ int compareit(float a, float b) {
173219
j = numeric_limits<float>::infinity();
174220
return 0;
175221

176-
}
222+
}

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

+53-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
11
// Use of NAN macro will trigger a warning "infinity defined in macro" because
22
// on Windows the NAN macro is defined using INFINITY. See below.
33

4-
// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan -triple powerpc64le-unknown-unknown %s \
5-
// RUN: -menable-no-infs -menable-no-nans
4+
// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \
5+
// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \
6+
// RUN: -menable-no-nans -std=c++23
67

7-
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown %s
8+
// RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \
9+
// RUN: -triple powerpc64le-unknown-unknown %s -menable-no-infs \
10+
// RUN: -menable-no-nans -funsafe-math-optimizations -std=c++23
11+
12+
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \
13+
// RUN: %s -std=c++23
14+
15+
// RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \
16+
// RUN: -menable-no-infs -std=c++23
817

918
// RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \
10-
// RUN: -menable-no-infs
19+
// RUN: -menable-no-infs -funsafe-math-optimizations -std=c++23
20+
21+
// RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \
22+
// RUN: -menable-no-nans -std=c++23
1123

1224
// RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \
13-
// RUN: -menable-no-nans
25+
// RUN: -funsafe-math-optimizations -menable-no-nans -std=c++23
26+
27+
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \
28+
// RUN: %s -Wno-nan-infinity-disabled -menable-no-infs -std=c++23
29+
30+
// RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \
31+
// RUN: %s -Wno-nan-infinity-disabled -menable-no-nans -std=c++23
1432

1533
// no-fast-no-diagnostics
1634

@@ -136,13 +154,41 @@ int compareit(float a, float b) {
136154
// no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
137155
p = __builtin_isfinite(a);
138156

139-
// These should NOT warn, since they are not using NaN or infinity.
157+
// These should NOT warn, since they are not using NaN or infinity.
140158
j = a > 1.1;
141159
j = b < 1.1;
142160
j = a >= 1.1;
143161
j = b <= 1.1;
144162
j = isunorderedf(a, b);
145163

164+
#ifndef INFINITY
165+
j = a;
166+
#endif
167+
#ifndef NAN
168+
j = b;
169+
#endif
170+
#ifdef INFINITY
171+
j = a;
172+
#endif
173+
#ifdef NAN
174+
j = b;
175+
#endif
176+
#if defined(INFINITY)
177+
j = a;
178+
#elifndef(INFINITY)
179+
j = b;
180+
#endif
181+
#if defined(INFINITY)
182+
j = a;
183+
#elifndef(NAN)
184+
j = b;
185+
#endif
186+
#if defined(NAN)
187+
j = a;
188+
#elifndef(INFINITY)
189+
j = b;
190+
#endif
191+
146192
// no-inf-no-nan-warning@+4 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point option}}
147193
// no-inf-no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}}
148194
// no-inf-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}}
@@ -176,4 +222,4 @@ int compareit(float a, float b) {
176222
j = numeric_limits<float>::infinity();
177223
return 0;
178224

179-
}
225+
}

0 commit comments

Comments
 (0)