Skip to content

Commit

Permalink
Document and add suppressions for our intentional use of & and |.
Browse files Browse the repository at this point in the history
This just came up again in #7272 and b/348626771 / cl/645390331.

Fixes #7272

RELNOTES=n/a
PiperOrigin-RevId: 646103257
  • Loading branch information
cpovirk authored and Google Java Core Libraries committed Jun 24, 2024
1 parent faf36af commit f46b178
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 22 deletions.
9 changes: 8 additions & 1 deletion android/guava/src/com/google/common/math/DoubleMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ static double roundIntermediate(double x, RoundingMode mode) {
* </ul>
*/
@GwtIncompatible // #roundIntermediate
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static int roundToInt(double x, RoundingMode mode) {
double z = roundIntermediate(x, mode);
checkInRangeForRoundingInputs(
Expand All @@ -154,6 +156,8 @@ public static int roundToInt(double x, RoundingMode mode) {
* </ul>
*/
@GwtIncompatible // #roundIntermediate
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long roundToLong(double x, RoundingMode mode) {
double z = roundIntermediate(x, mode);
checkInRangeForRoundingInputs(
Expand Down Expand Up @@ -181,6 +185,8 @@ public static long roundToLong(double x, RoundingMode mode) {
*/
// #roundIntermediate, java.lang.Math.getExponent, com.google.common.math.DoubleUtils
@GwtIncompatible
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static BigInteger roundToBigInteger(double x, RoundingMode mode) {
x = roundIntermediate(x, mode);
if (MIN_LONG_AS_DOUBLE - x < 1.0 & x < MAX_LONG_AS_DOUBLE_PLUS_ONE) {
Expand Down Expand Up @@ -235,7 +241,8 @@ public static double log2(double x) {
* infinite
*/
@GwtIncompatible // java.lang.Math.getExponent, com.google.common.math.DoubleUtils
@SuppressWarnings("fallthrough")
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings({"fallthrough", "ShortCircuitBoolean"})
public static int log2(double x, RoundingMode mode) {
checkArgument(x > 0.0 && isFinite(x), "x must be positive and finite");
int exponent = getExponent(x);
Expand Down
11 changes: 8 additions & 3 deletions android/guava/src/com/google/common/math/IntMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
@GwtCompatible(emulated = true)
@ElementTypesAreNonnullByDefault
public final class IntMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

@VisibleForTesting static final int MAX_SIGNED_POWER_OF_TWO = 1 << (Integer.SIZE - 2);

/**
Expand Down Expand Up @@ -88,6 +86,8 @@ public static int floorPowerOfTwo(int x) {
* <p>This differs from {@code Integer.bitCount(x) == 1}, because {@code
* Integer.bitCount(Integer.MIN_VALUE) == 1}, but {@link Integer#MIN_VALUE} is not a power of two.
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static boolean isPowerOfTwo(int x) {
return x > 0 & (x & (x - 1)) == 0;
}
Expand Down Expand Up @@ -310,7 +310,8 @@ private static int sqrtFloor(int x) {
* @throws ArithmeticException if {@code q == 0}, or if {@code mode == UNNECESSARY} and {@code a}
* is not an integer multiple of {@code b}
*/
@SuppressWarnings("fallthrough")
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings({"fallthrough", "ShortCircuitBoolean"})
public static int divide(int p, int q, RoundingMode mode) {
checkNotNull(mode);
if (q == 0) {
Expand Down Expand Up @@ -485,6 +486,8 @@ public static int checkedMultiply(int a, int b) {
* @throws ArithmeticException if {@code b} to the {@code k}th power overflows in signed {@code
* int} arithmetic
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static int checkedPow(int b, int k) {
checkNonNegative("exponent", k);
switch (b) {
Expand Down Expand Up @@ -559,6 +562,8 @@ public static int saturatedMultiply(int a, int b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static int saturatedPow(int b, int k) {
checkNonNegative("exponent", k);
switch (b) {
Expand Down
11 changes: 9 additions & 2 deletions android/guava/src/com/google/common/math/LongMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@
@GwtCompatible(emulated = true)
@ElementTypesAreNonnullByDefault
public final class LongMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

@VisibleForTesting static final long MAX_SIGNED_POWER_OF_TWO = 1L << (Long.SIZE - 2);

/**
Expand Down Expand Up @@ -92,6 +90,7 @@ public static long floorPowerOfTwo(long x) {
* <p>This differs from {@code Long.bitCount(x) == 1}, because {@code
* Long.bitCount(Long.MIN_VALUE) == 1}, but {@link Long#MIN_VALUE} is not a power of two.
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static boolean isPowerOfTwo(long x) {
return x > 0 & (x & (x - 1)) == 0;
Expand Down Expand Up @@ -536,6 +535,7 @@ public static long gcd(long a, long b) {
*
* @throws ArithmeticException if {@code a + b} overflows in signed {@code long} arithmetic
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedAdd(long a, long b) {
long result = a + b;
Expand All @@ -549,6 +549,7 @@ public static long checkedAdd(long a, long b) {
* @throws ArithmeticException if {@code a - b} overflows in signed {@code long} arithmetic
*/
@GwtIncompatible // TODO
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedSubtract(long a, long b) {
long result = a - b;
Expand All @@ -561,6 +562,7 @@ public static long checkedSubtract(long a, long b) {
*
* @throws ArithmeticException if {@code a * b} overflows in signed {@code long} arithmetic
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedMultiply(long a, long b) {
// Hacker's Delight, Section 2-12
Expand Down Expand Up @@ -596,6 +598,7 @@ public static long checkedMultiply(long a, long b) {
* long} arithmetic
*/
@GwtIncompatible // TODO
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedPow(long b, int k) {
checkNonNegative("exponent", k);
Expand Down Expand Up @@ -644,6 +647,7 @@ public static long checkedPow(long b, int k) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedAdd(long a, long b) {
long naiveSum = a + b;
Expand All @@ -662,6 +666,7 @@ public static long saturatedAdd(long a, long b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedSubtract(long a, long b) {
long naiveDifference = a - b;
Expand All @@ -680,6 +685,7 @@ public static long saturatedSubtract(long a, long b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedMultiply(long a, long b) {
// see checkedMultiply for explanation
Expand Down Expand Up @@ -710,6 +716,7 @@ public static long saturatedMultiply(long a, long b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedPow(long b, int k) {
checkNonNegative("exponent", k);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
/** Implementations of {@code Futures.catching*}. */
@GwtCompatible
@ElementTypesAreNonnullByDefault
@SuppressWarnings("nullness") // TODO(b/147136275): Remove once our checker understands & and |.
@SuppressWarnings({
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
"ShortCircuitBoolean",
"nullness", // TODO(b/147136275): Remove once our checker understands & and |.
})
abstract class AbstractCatchingFuture<
V extends @Nullable Object, X extends Throwable, F, T extends @Nullable Object>
extends FluentFuture.TrustedFuture<V> implements Runnable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,15 @@
* @since 1.0
*/
@SuppressWarnings({
"ShortCircuitBoolean", // we use non-short circuiting comparisons intentionally
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
"ShortCircuitBoolean",
"nullness", // TODO(b/147136275): Remove once our checker understands & and |.
})
@GwtCompatible(emulated = true)
@ReflectionSupport(value = ReflectionSupport.Level.FULL)
@ElementTypesAreNonnullByDefault
public abstract class AbstractFuture<V extends @Nullable Object> extends InternalFutureFailureAccess
implements ListenableFuture<V> {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

static final boolean GENERATE_CANCELLATION_CAUSES;

static {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
/** Implementations of {@code Futures.transform*}. */
@GwtCompatible
@ElementTypesAreNonnullByDefault
@SuppressWarnings("nullness") // TODO(b/147136275): Remove once our checker understands & and |.
@SuppressWarnings({
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
"ShortCircuitBoolean",
"nullness", // TODO(b/147136275): Remove once our checker understands & and |.
})
abstract class AbstractTransformFuture<
I extends @Nullable Object, O extends @Nullable Object, F, T extends @Nullable Object>
extends FluentFuture.TrustedFuture<O> implements Runnable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
*/
@GwtCompatible
@ElementTypesAreNonnullByDefault
@SuppressWarnings(
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
"ShortCircuitBoolean")
abstract class AggregateFuture<InputT extends @Nullable Object, OutputT extends @Nullable Object>
extends AggregateFutureState<OutputT> {
private static final LazyLogger logger = new LazyLogger(AggregateFuture.class);
Expand Down
9 changes: 8 additions & 1 deletion guava/src/com/google/common/math/DoubleMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ static double roundIntermediate(double x, RoundingMode mode) {
* </ul>
*/
@GwtIncompatible // #roundIntermediate
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static int roundToInt(double x, RoundingMode mode) {
double z = roundIntermediate(x, mode);
checkInRangeForRoundingInputs(
Expand All @@ -154,6 +156,8 @@ public static int roundToInt(double x, RoundingMode mode) {
* </ul>
*/
@GwtIncompatible // #roundIntermediate
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long roundToLong(double x, RoundingMode mode) {
double z = roundIntermediate(x, mode);
checkInRangeForRoundingInputs(
Expand Down Expand Up @@ -181,6 +185,8 @@ public static long roundToLong(double x, RoundingMode mode) {
*/
// #roundIntermediate, java.lang.Math.getExponent, com.google.common.math.DoubleUtils
@GwtIncompatible
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static BigInteger roundToBigInteger(double x, RoundingMode mode) {
x = roundIntermediate(x, mode);
if (MIN_LONG_AS_DOUBLE - x < 1.0 & x < MAX_LONG_AS_DOUBLE_PLUS_ONE) {
Expand Down Expand Up @@ -235,7 +241,8 @@ public static double log2(double x) {
* infinite
*/
@GwtIncompatible // java.lang.Math.getExponent, com.google.common.math.DoubleUtils
@SuppressWarnings("fallthrough")
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings({"fallthrough", "ShortCircuitBoolean"})
public static int log2(double x, RoundingMode mode) {
checkArgument(x > 0.0 && isFinite(x), "x must be positive and finite");
int exponent = getExponent(x);
Expand Down
11 changes: 8 additions & 3 deletions guava/src/com/google/common/math/IntMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
@GwtCompatible(emulated = true)
@ElementTypesAreNonnullByDefault
public final class IntMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

@VisibleForTesting static final int MAX_SIGNED_POWER_OF_TWO = 1 << (Integer.SIZE - 2);

/**
Expand Down Expand Up @@ -88,6 +86,8 @@ public static int floorPowerOfTwo(int x) {
* <p>This differs from {@code Integer.bitCount(x) == 1}, because {@code
* Integer.bitCount(Integer.MIN_VALUE) == 1}, but {@link Integer#MIN_VALUE} is not a power of two.
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static boolean isPowerOfTwo(int x) {
return x > 0 & (x & (x - 1)) == 0;
}
Expand Down Expand Up @@ -310,7 +310,8 @@ private static int sqrtFloor(int x) {
* @throws ArithmeticException if {@code q == 0}, or if {@code mode == UNNECESSARY} and {@code a}
* is not an integer multiple of {@code b}
*/
@SuppressWarnings("fallthrough")
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings({"fallthrough", "ShortCircuitBoolean"})
public static int divide(int p, int q, RoundingMode mode) {
checkNotNull(mode);
if (q == 0) {
Expand Down Expand Up @@ -485,6 +486,8 @@ public static int checkedMultiply(int a, int b) {
* @throws ArithmeticException if {@code b} to the {@code k}th power overflows in signed {@code
* int} arithmetic
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static int checkedPow(int b, int k) {
checkNonNegative("exponent", k);
switch (b) {
Expand Down Expand Up @@ -559,6 +562,8 @@ public static int saturatedMultiply(int a, int b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static int saturatedPow(int b, int k) {
checkNonNegative("exponent", k);
switch (b) {
Expand Down
11 changes: 9 additions & 2 deletions guava/src/com/google/common/math/LongMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@
@GwtCompatible(emulated = true)
@ElementTypesAreNonnullByDefault
public final class LongMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

@VisibleForTesting static final long MAX_SIGNED_POWER_OF_TWO = 1L << (Long.SIZE - 2);

/**
Expand Down Expand Up @@ -92,6 +90,7 @@ public static long floorPowerOfTwo(long x) {
* <p>This differs from {@code Long.bitCount(x) == 1}, because {@code
* Long.bitCount(Long.MIN_VALUE) == 1}, but {@link Long#MIN_VALUE} is not a power of two.
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static boolean isPowerOfTwo(long x) {
return x > 0 & (x & (x - 1)) == 0;
Expand Down Expand Up @@ -536,6 +535,7 @@ public static long gcd(long a, long b) {
*
* @throws ArithmeticException if {@code a + b} overflows in signed {@code long} arithmetic
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedAdd(long a, long b) {
long result = a + b;
Expand All @@ -549,6 +549,7 @@ public static long checkedAdd(long a, long b) {
* @throws ArithmeticException if {@code a - b} overflows in signed {@code long} arithmetic
*/
@GwtIncompatible // TODO
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedSubtract(long a, long b) {
long result = a - b;
Expand All @@ -561,6 +562,7 @@ public static long checkedSubtract(long a, long b) {
*
* @throws ArithmeticException if {@code a * b} overflows in signed {@code long} arithmetic
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedMultiply(long a, long b) {
// Hacker's Delight, Section 2-12
Expand Down Expand Up @@ -596,6 +598,7 @@ public static long checkedMultiply(long a, long b) {
* long} arithmetic
*/
@GwtIncompatible // TODO
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long checkedPow(long b, int k) {
checkNonNegative("exponent", k);
Expand Down Expand Up @@ -644,6 +647,7 @@ public static long checkedPow(long b, int k) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedAdd(long a, long b) {
long naiveSum = a + b;
Expand All @@ -662,6 +666,7 @@ public static long saturatedAdd(long a, long b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedSubtract(long a, long b) {
long naiveDifference = a - b;
Expand All @@ -680,6 +685,7 @@ public static long saturatedSubtract(long a, long b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedMultiply(long a, long b) {
// see checkedMultiply for explanation
Expand Down Expand Up @@ -710,6 +716,7 @@ public static long saturatedMultiply(long a, long b) {
*
* @since 20.0
*/
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@SuppressWarnings("ShortCircuitBoolean")
public static long saturatedPow(long b, int k) {
checkNonNegative("exponent", k);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
/** Implementations of {@code Futures.catching*}. */
@GwtCompatible
@ElementTypesAreNonnullByDefault
@SuppressWarnings("nullness") // TODO(b/147136275): Remove once our checker understands & and |.
@SuppressWarnings({
// Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
"ShortCircuitBoolean",
"nullness", // TODO(b/147136275): Remove once our checker understands & and |.
})
abstract class AbstractCatchingFuture<
V extends @Nullable Object, X extends Throwable, F, T extends @Nullable Object>
extends FluentFuture.TrustedFuture<V> implements Runnable {
Expand Down
Loading

0 comments on commit f46b178

Please sign in to comment.