Skip to content

Commit aff5ff1

Browse files
committed
8244681: Add a warning for possibly lossy conversion in compound assignments
8293797: Release Note: Javac warns about type casts in compound assignments with possible lossy conversions Reviewed-by: erikj, prr
1 parent 15cb1fb commit aff5ff1

File tree

13 files changed

+438
-1
lines changed

13 files changed

+438
-1
lines changed

make/CompileDemos.gmk

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ $(eval $(call SetupBuildDemo, Font2DTest, \
189189
$(eval $(call SetupBuildDemo, J2Ddemo, \
190190
DEMO_SUBDIR := jfc, \
191191
MAIN_CLASS := java2d.J2Ddemo, \
192-
DISABLED_WARNINGS := rawtypes deprecation unchecked cast, \
192+
DISABLED_WARNINGS := rawtypes deprecation unchecked cast lossy-conversions, \
193193
JAR_NAME := J2Ddemo, \
194194
))
195195

make/modules/java.desktop/Java.gmk

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# questions.
2424
#
2525

26+
DISABLED_WARNINGS_java += lossy-conversions
2627
DOCLINT += -Xdoclint:all/protected \
2728
'-Xdoclint/package:java.*,javax.*'
2829
COPY += .gif .png .wav .txt .xml .css .pf

make/modules/java.xml/Java.gmk

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# questions.
2424
#
2525

26+
DISABLED_WARNINGS_java += lossy-conversions
2627
DOCLINT += -Xdoclint:all/protected \
2728
'-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \
2829
javax.xml.transform javax.xml.validation javax.xml.xpath)'

make/modules/jdk.naming.dns/Java.gmk

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DISABLED_WARNINGS_java += lossy-conversions

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java

+5
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ public enum LintCategory {
214214
*/
215215
FINALLY("finally"),
216216

217+
/**
218+
* Warn about compiler possible lossy conversions.
219+
*/
220+
LOSSY_CONVERSIONS("lossy-conversions"),
221+
217222
/**
218223
* Warn about compiler generation of a default constructor.
219224
*/

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

+1
Original file line numberDiff line numberDiff line change
@@ -3941,6 +3941,7 @@ public void visitAssignop(JCAssignOp tree) {
39413941
chk.checkCastable(tree.rhs.pos(),
39423942
operator.type.getReturnType(),
39433943
owntype);
3944+
chk.checkLossOfPrecision(tree.rhs.pos(), operand, owntype);
39443945
}
39453946
result = check(tree, owntype, KindSelector.VAL, resultInfo);
39463947
}

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java

+16
Original file line numberDiff line numberDiff line change
@@ -3751,6 +3751,22 @@ void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
37513751
}
37523752
}
37533753

3754+
/**
3755+
* Check for possible loss of precission
3756+
* @param pos Position for error reporting.
3757+
* @param found The computed type of the tree
3758+
* @param req The computed type of the tree
3759+
*/
3760+
void checkLossOfPrecision(final DiagnosticPosition pos, Type found, Type req) {
3761+
if (found.isNumeric() && req.isNumeric() && !types.isAssignable(found, req)) {
3762+
deferredLintHandler.report(() -> {
3763+
if (lint.isEnabled(LintCategory.LOSSY_CONVERSIONS))
3764+
log.warning(LintCategory.LOSSY_CONVERSIONS,
3765+
pos, Warnings.PossibleLossOfPrecision(found, req));
3766+
});
3767+
}
3768+
}
3769+
37543770
/**
37553771
* Check for empty statements after if
37563772
*/

src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties

+4
Original file line numberDiff line numberDiff line change
@@ -2527,6 +2527,10 @@ compiler.misc.not.applicable.types=\
25272527
compiler.misc.possible.loss.of.precision=\
25282528
possible lossy conversion from {0} to {1}
25292529

2530+
# 0: type, 1: type
2531+
compiler.warn.possible.loss.of.precision=\
2532+
implicit cast from {0} to {1} in compound assignment is possibly lossy
2533+
25302534
compiler.misc.unchecked.assign=\
25312535
unchecked conversion
25322536

src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties

+3
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ javac.opt.Xlint.desc.fallthrough=\
210210
javac.opt.Xlint.desc.finally=\
211211
Warn about finally clauses that do not terminate normally.
212212

213+
javac.opt.Xlint.desc.lossy-conversions=\
214+
Warn about possible lossy conversions in compound assignment.
215+
213216
javac.opt.Xlint.desc.module=\
214217
Warn about module system related issues.
215218

src/jdk.compiler/share/man/javac.1

+3
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,9 @@ switch statement to the next.
783783
\f[CB]finally\f[R]: Warns about \f[CB]finally\f[R] clauses that do not
784784
terminate normally.
785785
.IP \[bu] 2
786+
\f[CB]lossy\-conversions\f[R]: Warns about possible lossy conversions
787+
in compound assignment.
788+
.IP \[bu] 2
786789
\f[CB]missing\-explicit\-ctor\f[R]: Warns about missing explicit
787790
constructors in public and protected classes in exported packages.
788791
.IP \[bu] 2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
// key: compiler.warn.possible.loss.of.precision
25+
// options: -Xlint:lossy-conversions
26+
27+
class LossyConversion {
28+
void m(int a) {
29+
a += 1.0;
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
* @test /nodynamiccopyright/
3+
* @bug 8244681
4+
* @summary Test for -Xlint:lossy-conversions
5+
*
6+
* @compile/fail/ref=LossyConversions.out -XDrawDiagnostics -Xmaxwarns 200 -Xlint:lossy-conversions -Werror LossyConversions.java
7+
*/
8+
9+
public class LossyConversions {
10+
11+
public void lossyConversions() {
12+
byte a = 0;
13+
a += 1.0; a -= 2.0; a *= 3.0; a /= 4.0;
14+
a += 11; a -= 12; a *= 13; a /= 14; //no warnings - within range
15+
a |= 15; a &= 16; a ^= 17; a %= 18; //no warnings - within range
16+
a += 21l; a -= 22l; a *= 23l; a /= 24l;
17+
a |= 25l; a &= 26l; a ^= 27l; a %= 28l;
18+
a += 1001; a -= 1002; a *= 1003; a /= 1004;
19+
a |= 1005; a &= 1006; a ^= 1007; a %= 1008;
20+
a += 100_001; a -= 100_002; a *= 100_003; a /= 100_004;
21+
a |= 100_005; a &= 100_006; a ^= 100_007; a %= 100_008;
22+
a += 10_000_000_001l; a -= 10_000_000_002l; a *= 10_000_000_003l; a /= 10_000_000_004l;
23+
a |= 10_000_000_005l; a &= 10_000_000_006l; a ^= 10_000_000_007l; a %= 10_000_000_008l;
24+
25+
short b = 0;
26+
b += 1.0; b -= 2.0; b *= 3.0; b /= 4.0;
27+
b += 11; b -= 12; b *= 13; b /= 14; //no warnings - within range
28+
b |= 15; b &= 16; b ^= 17; b %= 18; //no warnings - within range
29+
b += 21l; b -= 22l; b *= 23l; b /= 24l;
30+
b |= 25l; b &= 26l; b ^= 27l; b %= 28l;
31+
b += 1001; b -= 1002; b *= 1003; b /= 1004; //no warnings - within range
32+
b |= 1005; b &= 1006; b ^= 1007; b %= 1008; //no warnings - within range
33+
b += 100_001; b -= 100_002; b *= 100_003; b /= 100_004;
34+
b |= 100_005; b &= 100_006; b ^= 100_007; b %= 100_008;
35+
b += 10_000_000_001l; b -= 10_000_000_002l; b *= 10_000_000_003l; b /= 10_000_000_004l;
36+
b |= 10_000_000_005l; b &= 10_000_000_006l; b ^= 10_000_000_007l; b %= 10_000_000_008l;
37+
38+
int c = 0;
39+
c += 1.0; c -= 2.0; c *= 3.0; c /= 4.0;
40+
c += 11; c -= 12; c *= 13; c /= 14; //no warnings
41+
c |= 15; c &= 16; c ^= 17; c %= 18; //no warnings
42+
c += 21l; c -= 22l; c *= 23l; c /= 24l;
43+
c |= 25l; c &= 26l; c ^= 27l; c %= 28l;
44+
c += 1001; c -= 1002; c *= 1003; c /= 1004; //no warnings
45+
c |= 1005; c &= 1006; c ^= 1007; c %= 1008; //no warnings
46+
c += 100_001; c -= 100_002; c *= 100_003; c /= 100_004; //no warnings
47+
c |= 100_005; c &= 100_006; c ^= 100_007; c %= 100_008; //no warnings
48+
c += 10_000_000_001l; c -= 10_000_000_002l; c *= 10_000_000_003l; c /= 10_000_000_004l;
49+
c |= 10_000_000_005l; c &= 10_000_000_006l; c ^= 10_000_000_007l; c %= 10_000_000_008l;
50+
51+
long d = 0;
52+
d += 1.0; d -= 2.0; d *= 3.0; d /= 4.0;
53+
d += 11; d -= 12; d *= 13; d /= 14; //no warnings
54+
d |= 15; d &= 16; d ^= 17; d %= 18; //no warnings
55+
d += 21l; d -= 22l; d *= 23l; d /= 24l; //no warnings
56+
d |= 25l; d &= 26l; d ^= 27l; d %= 28l; //no warnings
57+
d += 1001; d -= 1002; d *= 1003; d /= 1004; //no warnings
58+
d |= 1005; d &= 1006; d ^= 1007; d %= 1008; //no warnings
59+
d += 100_001; d -= 100_002; d *= 100_003; d /= 100_004; //no warnings
60+
d |= 100_005; d &= 100_006; d ^= 100_007; d %= 100_008; //no warnings
61+
d += 10_000_000_001l; d -= 10_000_000_002l; d *= 10_000_000_003l; d /= 10_000_000_004l; //no warnings
62+
d |= 10_000_000_005l; d &= 10_000_000_006l; d ^= 10_000_000_007l; d %= 10_000_000_008l; //no warnings
63+
64+
float e = 0;
65+
e += 1.0; e -= 2.0; e *= 3.0; e /= 4.0;
66+
67+
double f = 1.0;
68+
f += 1.0; f -= 2.0; f *= 3.0; f /= 4.0; //no warnings
69+
70+
a += a; a -= a; a *= a; a /= a; //no warnings
71+
a |= a; a &= a; a ^= a; a %= a; //no warnings
72+
a += b; a -= b; a *= b; a /= b;
73+
a |= b; a &= b; a ^= b; a %= b;
74+
a += c; a -= c; a *= c; a /= c;
75+
a |= c; a &= c; a ^= c; a %= c;
76+
a += d; a -= d; a *= d; a /= d;
77+
a |= d; a &= d; a ^= d; a %= d;
78+
a += e; a -= e; a *= e; a /= e;
79+
a += f; a -= f; a *= f; a /= f;
80+
81+
b += a; b -= a; b *= a; b /= a; //no warnings
82+
b |= a; b &= a; b ^= a; b %= a; //no warnings
83+
b += b; b -= b; b *= b; b /= b; //no warnings
84+
b |= b; b &= b; b ^= b; b %= b; //no warnings
85+
b += c; b -= c; b *= c; b /= c;
86+
b |= c; b &= c; b ^= c; b %= c;
87+
b += d; b -= d; b *= d; b /= d;
88+
b |= d; b &= d; b ^= d; b %= d;
89+
b += e; b -= e; b *= e; b /= e;
90+
b += f; b -= f; b *= f; b /= f;
91+
92+
c += a; c -= a; c *= a; c /= a; //no warnings
93+
c |= a; c &= a; c ^= a; c %= a; //no warnings
94+
c += b; c -= b; c *= b; c /= b; //no warnings
95+
c |= b; c &= b; c ^= b; c %= b; //no warnings
96+
c += c; c -= c; c *= c; c /= c; //no warnings
97+
c |= c; c &= c; c ^= c; c %= c; //no warnings
98+
c += d; c -= d; c *= d; c /= d;
99+
c |= d; c &= d; c ^= d; c %= d;
100+
c += e; c -= e; c *= e; c /= e;
101+
c += f; c -= f; c *= f; c /= f;
102+
103+
d += a; d -= a; d *= a; d /= a; //no warnings
104+
d |= a; d &= a; d ^= a; d %= a; //no warnings
105+
d += b; d -= b; d *= b; d /= b; //no warnings
106+
d |= b; d &= b; d ^= b; d %= b; //no warnings
107+
d += c; d -= c; d *= c; d /= c; //no warnings
108+
d |= c; d &= c; d ^= c; d %= c; //no warnings
109+
d += d; d -= d; d *= d; d /= d; //no warnings
110+
d |= d; d &= d; d ^= d; d %= d; //no warnings
111+
d += e; d -= e; d *= e; d /= e;
112+
d += f; d -= f; d *= f; d /= f;
113+
114+
e += a; e -= a; e *= a; e /= a; //no warnings
115+
e += b; e -= b; e *= b; e /= b; //no warnings
116+
e += c; e -= c; e *= c; e /= c; //no warnings
117+
e += d; e -= d; e *= d; e /= d; //no warnings
118+
e += e; e -= e; e *= e; e /= e; //no warnings
119+
e += f; e -= f; e *= f; e /= f;
120+
121+
f += a; f -= a; f *= a; f /= a; //no warnings
122+
f += b; f -= b; f *= b; f /= b; //no warnings
123+
f += c; f -= c; f *= c; f /= c; //no warnings
124+
f += d; f -= d; f *= d; f /= d; //no warnings
125+
f += e; f -= e; f *= e; f /= e; //no warnings
126+
f += f; f -= f; f *= f; f /= f; //no warnings
127+
}
128+
129+
@SuppressWarnings("lossy-conversions")
130+
public void suppressedLossyConversions() {
131+
byte a = 0;
132+
a += 1.0; a -= 2.0; a *= 3.0; a /= 4.0;
133+
a += 21l; a -= 22l; a *= 23l; a /= 24l;
134+
a |= 25l; a &= 26l; a ^= 27l; a %= 28l;
135+
a += 1001; a -= 1002; a *= 1003; a /= 1004;
136+
a |= 1005; a &= 1006; a ^= 1007; a %= 1008;
137+
a += 100_001; a -= 100_002; a *= 100_003; a /= 100_004;
138+
a |= 100_005; a &= 100_006; a ^= 100_007; a %= 100_008;
139+
a += 10_000_000_001l; a -= 10_000_000_002l; a *= 10_000_000_003l; a /= 10_000_000_004l;
140+
a |= 10_000_000_005l; a &= 10_000_000_006l; a ^= 10_000_000_007l; a %= 10_000_000_008l;
141+
142+
short b = 0;
143+
b += 1.0; b -= 2.0; b *= 3.0; b /= 4.0;
144+
b += 21l; b -= 22l; b *= 23l; b /= 24l;
145+
b |= 25l; b &= 26l; b ^= 27l; b %= 28l;
146+
b += 100_001; b -= 100_002; b *= 100_003; b /= 100_004;
147+
b |= 100_005; b &= 100_006; b ^= 100_007; b %= 100_008;
148+
b += 10_000_000_001l; b -= 10_000_000_002l; b *= 10_000_000_003l; b /= 10_000_000_004l;
149+
b |= 10_000_000_005l; b &= 10_000_000_006l; b ^= 10_000_000_007l; b %= 10_000_000_008l;
150+
151+
int c = 0;
152+
c += 1.0; c -= 2.0; c *= 3.0; c /= 4.0;
153+
c += 21l; c -= 22l; c *= 23l; c /= 24l;
154+
c |= 25l; c &= 26l; c ^= 27l; c %= 28l;
155+
c += 10_000_000_001l; c -= 10_000_000_002l; c *= 10_000_000_003l; c /= 10_000_000_004l;
156+
c |= 10_000_000_005l; c &= 10_000_000_006l; c ^= 10_000_000_007l; c %= 10_000_000_008l;
157+
158+
long d = 0;
159+
d += 1.0; d -= 2.0; d *= 3.0; d /= 4.0;
160+
161+
float e = 0;
162+
e += 1.0; e -= 2.0; e *= 3.0; e /= 4.0;
163+
164+
double f = 1.0;
165+
166+
a += b; a -= b; a *= b; a /= b;
167+
a |= b; a &= b; a ^= b; a %= b;
168+
a += c; a -= c; a *= c; a /= c;
169+
a |= c; a &= c; a ^= c; a %= c;
170+
a += d; a -= d; a *= d; a /= d;
171+
a |= d; a &= d; a ^= d; a %= d;
172+
a += e; a -= e; a *= e; a /= e;
173+
a += f; a -= f; a *= f; a /= f;
174+
175+
b += c; b -= c; b *= c; b /= c;
176+
b |= c; b &= c; b ^= c; b %= c;
177+
b += d; b -= d; b *= d; b /= d;
178+
b |= d; b &= d; b ^= d; b %= d;
179+
b += e; b -= e; b *= e; b /= e;
180+
b += f; b -= f; b *= f; b /= f;
181+
182+
c += d; c -= d; c *= d; c /= d;
183+
c |= d; c &= d; c ^= d; c %= d;
184+
c += e; c -= e; c *= e; c /= e;
185+
c += f; c -= f; c *= f; c /= f;
186+
187+
d += e; d -= e; d *= e; d /= e;
188+
d += f; d -= f; d *= f; d /= f;
189+
190+
e += f; e -= f; e *= f; e /= f;
191+
}
192+
}

0 commit comments

Comments
 (0)