Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/ddmd/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -6016,12 +6016,11 @@ extern (C++) abstract class BinExp : Expression

// T opAssign floating yields a floating. Prevent truncating conversions (float to int).
// See issue 3841.
// Should we also prevent double to float (type.isfloating() && type.size() < t2.size()) ?
if (op == TOKaddass || op == TOKminass ||
op == TOKmulass || op == TOKdivass || op == TOKmodass ||
op == TOKpowass)
{
if ((type.isintegral() && t2.isfloating()))
if ((type.isintegral() && t2.isfloating()) || (type.isfloating() && type.size() < t2.size()))
{
warning("%s %s %s is performing truncating conversion", type.toChars(), Token.toChars(op), t2.toChars());
}
Expand Down
11 changes: 11 additions & 0 deletions src/ddmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -5396,6 +5396,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
assert(exp.e1.type);
}
Type t1 = exp.e1.type.toBasetype();
Type oldt2;

/* Run this.e2 semantic.
* Different from other binary expressions, the analysis of e2
Expand All @@ -5414,7 +5415,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (e2x.checkValue())
return setError();

exp.e2 = e2x;
if (e2x.type)
oldt2 = e2x.type;
}

/* Rewrite tuple assignment as a tuple of assignments.
Expand Down Expand Up @@ -6144,6 +6148,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.e2 = e2x;
t2 = exp.e2.type.toBasetype();

if (oldt2 && oldt2.isfloating() && exp.e1.type.isfloating() &&
exp.e1.type.size() < oldt2.size())
{
exp.warning("%s = %s is performing truncating conversion",
exp.e1.type.toChars(), oldt2.toChars());
}

/* Look for array operations
*/
if ((t2.ty == Tarray || t2.ty == Tsarray) && isArrayOpValid(exp.e2))
Expand Down
7 changes: 7 additions & 0 deletions src/ddmd/statementsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2928,6 +2928,13 @@ else
*/
}

if (rs && rs.exp && tret && tret.isfloating() && rs.exp.type.isfloating() &&
tret.size() < rs.exp.type.size())
{
rs.warning("return %s from %s function is performing truncating conversion",
rs.exp.type.toChars(), tret.toChars());
}

// handle NRVO
if (fd.nrvo_can && rs.exp.op == TOKvar)
{
Expand Down
24 changes: 24 additions & 0 deletions test/fail_compilation/warn17933.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// REQUIRED_ARGS: -w

/*
TEST_OUTPUT:
---
fail_compilation/warn17933.d(14): Warning: float = double is performing truncating conversion
fail_compilation/warn17933.d(15): Warning: float += double is performing truncating conversion
fail_compilation/warn17933.d(22): Warning: return double from float function is performing truncating conversion
---
*/

void test17933()
{
float f;
double d;
f = d;
f += 0.1;
}

float testReturn(float f)
{
return f * 0.5;
}