More warnings when double truncation to float: compound assignment is supported now.

llvm-svn: 327618
This commit is contained in:
Andrew V. Tischenko 2018-03-15 10:03:35 +00:00
parent f9b8035f3c
commit 5704dc0c7f
3 changed files with 40 additions and 3 deletions

View File

@ -3093,6 +3093,9 @@ def err_impcast_complex_scalar : Error<
def warn_impcast_float_precision : Warning<
"implicit conversion loses floating-point precision: %0 to %1">,
InGroup<Conversion>, DefaultIgnore;
def warn_impcast_float_result_precision : Warning<
"implicit conversion when assigning computation result loses floating-point precision: %0 to %1">,
InGroup<Conversion>, DefaultIgnore;
def warn_impcast_double_promotion : Warning<
"implicit conversion increases floating-point precision: %0 to %1">,
InGroup<DoublePromotion>, DefaultIgnore;

View File

@ -9183,6 +9183,32 @@ static void DiagnoseImpCast(Sema &S, Expr *E, QualType T,
DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);
}
/// Analyze the given compound assignment for the possible losing of
/// floating-point precision.
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
assert(isa<CompoundAssignOperator>(E) &&
"Must be compound assignment operation");
// Recurse on the LHS and RHS in here
AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
// Now check the outermost expression
const auto *ResultBT = E->getLHS()->getType()->getAs<BuiltinType>();
const auto *RBT = cast<CompoundAssignOperator>(E)
->getComputationResultType()
->getAs<BuiltinType>();
// If both source and target are floating points.
if (ResultBT && ResultBT->isFloatingPoint() && RBT && RBT->isFloatingPoint())
// Builtin FP kinds are ordered by increasing FP rank.
if (ResultBT->getKind() < RBT->getKind())
// We don't want to warn for system macro.
if (!S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
// warn about dropping FP rank.
DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(),
E->getOperatorLoc(),
diag::warn_impcast_float_result_precision);
}
/// Diagnose an implicit cast from a floating point value to an integer value.
static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
@ -9550,7 +9576,7 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
return;
return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_vector_scalar);
}
// If the vector cast is cast between two vectors of the same size, it is
// a bitcast, not a conversion.
if (S.Context.getTypeSize(Source) == S.Context.getTypeSize(Target))
@ -9827,7 +9853,7 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,
if (E->isTypeDependent() || E->isValueDependent())
return;
// For conditional operators, we analyze the arguments as if they
// were being fed directly into the output.
if (isa<ConditionalOperator>(E)) {
@ -9871,6 +9897,9 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,
// And with simple assignments.
if (BO->getOpcode() == BO_Assign)
return AnalyzeAssignment(S, BO);
// And with compound assignments.
if (BO->isAssignmentOp())
return AnalyzeCompoundAssignment(S, BO);
}
// These break the otherwise-useful invariant below. Fortunately,

View File

@ -436,10 +436,15 @@ float double2float_test1(double a) {
}
void double2float_test2(double a, float *b) {
*b += a;
*b += a; // expected-warning {{implicit conversion when assigning computation result loses floating-point precision: 'double' to 'float'}}
}
float sinf (float x);
double double2float_test3(double a) {
return sinf(a); // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'float'}}
}
float double2float_test4(double a, float b) {
b -= a; // expected-warning {{implicit conversion when assigning computation result loses floating-point precision: 'double' to 'float'}}
return b;
}