def IntConversion : DiagGroup<"int-conversion">;
def EnumConversion : DiagGroup<"enum-conversion">;
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion">;
-def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion">;
-def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion", [ImplicitIntFloatConversion]>;
+def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion">;
def ImplicitFixedPointConversion : DiagGroup<"implicit-fixed-point-conversion">;
def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">;
"implicit conversion turns floating-point number into integer: %0 to %1">,
InGroup<FloatConversion>, DefaultIgnore;
-// Implicit int -> float conversion precision loss warnings.
-def warn_impcast_integer_float_precision : Warning<
- "implicit conversion from %0 to %1 may lose precision">,
- InGroup<ImplicitIntFloatConversion>, DefaultIgnore;
-def warn_impcast_integer_float_precision_constant : Warning<
- "implicit conversion from %2 to %3 changes value from %0 to %1">,
- InGroup<ImplicitIntFloatConversion>;
-
def warn_impcast_float_to_integer : Warning<
"implicit conversion from %0 to %1 changes value from %2 to %3">,
InGroup<FloatOverflowConversion>, DefaultIgnore;
}
}
- // If we are casting an integer type to a floating point type, we might
- // lose accuracy if the floating point type has a narrower significand
- // than the integer type. Issue warnings for that accuracy loss.
- if (SourceBT && TargetBT && SourceBT->isIntegerType() &&
- TargetBT->isFloatingType()) {
- // Determine the number of precision bits in the source integer type.
- IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());
- unsigned int SourcePrecision = SourceRange.Width;
-
- // Determine the number of precision bits in the
- // target floating point type.
- unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
- S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)));
-
- if (SourcePrecision > 0 && TargetPrecision > 0 &&
- SourcePrecision > TargetPrecision) {
-
- llvm::APSInt SourceInt;
- if (E->isIntegerConstantExpr(SourceInt, S.Context)) {
- // If the source integer is a constant, convert it to the target
- // floating point type. Issue a warning if the value changes
- // during the whole conversion.
- llvm::APFloat TargetFloatValue(
- S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)));
- llvm::APFloat::opStatus ConversionStatus =
- TargetFloatValue.convertFromAPInt(SourceInt,
- SourceBT->isSignedInteger(), llvm::APFloat::rmNearestTiesToEven);
-
- if (ConversionStatus != llvm::APFloat::opOK) {
- std::string PrettySourceValue = SourceInt.toString(10);
- SmallString<32> PrettyTargetValue;
- TargetFloatValue.toString(PrettyTargetValue,
- TargetPrecision);
-
- S.DiagRuntimeBehavior(
- E->getExprLoc(), E,
- S.PDiag(diag::warn_impcast_integer_float_precision_constant)
- << PrettySourceValue << PrettyTargetValue
- << E->getType() << T
- << E->getSourceRange() << clang::SourceRange(CC));
- }
- } else {
- // Otherwise, the implicit conversion may lose precision.
- DiagnoseImpCast(S, E, T, CC,
- diag::warn_impcast_integer_float_precision);
- }
- }
- }
-
DiagnoseNullConversion(S, E, T, CC);
S.DiscardMisalignedMemberAddress(Target, E);
takes_int(v);
takes_long(v);
takes_longlong(v);
- takes_float(v); // expected-warning {{implicit conversion from 'int' to 'float' may lose precision}}
+ takes_float(v);
takes_double(v);
takes_longdouble(v);
}
takes_int(v); // expected-warning {{implicit conversion loses integer precision}}
takes_long(v);
takes_longlong(v);
- takes_float(v); // expected-warning {{implicit conversion from 'long' to 'float' may lose precision}}
- takes_double(v); // expected-warning {{implicit conversion from 'long' to 'double' may lose precision}}
+ takes_float(v);
+ takes_double(v);
takes_longdouble(v);
}
takes_int(v); // expected-warning {{implicit conversion loses integer precision}}
takes_long(v);
takes_longlong(v);
- takes_float(v); // expected-warning {{implicit conversion from 'long long' to 'float' may lose precision}}
- takes_double(v); // expected-warning {{implicit conversion from 'long long' to 'double' may lose precision}}
+ takes_float(v);
+ takes_double(v);
takes_longdouble(v);
}
vl = vl + t; // expected-warning {{implicit conversion loses integer precision}}
vf = 1 + vf;
- vf = l + vf; // expected-warning {{implicit conversion from 'long' to 'float2' (vector of 2 'float' values) may lose precision}}
+ vf = l + vf;
vf = 2.0 + vf;
vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}}
- vf = vf + 0xffffffff; // expected-warning {{implicit conversion from 'unsigned int' to 'float2' (vector of 2 'float' values) changes value from 4294967295 to 4294967296}}
+ vf = vf + 0xffffffff;
vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}}
- vd = l + vd; // expected-warning {{implicit conversion from 'long' to 'double2' (vector of 2 'double' values) may lose precision}}
- vd = vd + t; // expected-warning {{implicit conversion from '__uint128_t' (aka 'unsigned __int128') to 'double2' (vector of 2 'double' values) may lose precision}}
+ vd = l + vd;
+ vd = vd + t;
}
+++ /dev/null
-// RUN: %clang_cc1 %s -verify -Wno-conversion -Wimplicit-int-float-conversion
-
-long testReturn(long a, float b) {
- return a + b; // expected-warning {{implicit conversion from 'long' to 'float' may lose precision}}
-}
-
-void testAssignment() {
- float f = 222222;
- double b = 222222222222L;
-
- float ff = 222222222222L; // expected-warning {{implicit conversion from 'long' to 'float' changes value from 222222222222 to 222222221312}}
- float ffff = 222222222222UL; // expected-warning {{implicit conversion from 'unsigned long' to 'float' changes value from 222222222222 to 222222221312}}
-
- long l = 222222222222L;
- float fff = l; // expected-warning {{implicit conversion from 'long' to 'float' may lose precision}}
-}
-
-void testExpression() {
- float a = 0.0f;
- float b = 222222222222L + a; // expected-warning {{implicit conversion from 'long' to 'float' changes value from 222222222222 to 222222221312}}
-
- float g = 22222222 + 22222222;
- float c = 22222222 + 22222223; // expected-warning {{implicit conversion from 'int' to 'float' changes value from 44444445 to 44444444}}
-
- int i = 0;
- float d = i + a; // expected-warning {{implicit conversion from 'int' to 'float' may lose precision}}
-
- double e = 0.0;
- double f = i + e;
-}