This is an archive of the discontinued LLVM Phabricator instance.

[Sema] add warning for tautological FP compare with literal
ClosedPublic

Authored by spatel on Mar 9 2022, 9:44 AM.

Details

Summary

If we are comparing an FP literal with a value that is casted from a type where the literal can't be represented, that's probably a programmer error.

This is a fix for:
https://github.com/llvm/llvm-project/issues/54222

Note - I added the optimizer change with:
9397bdc67eb2
...and as discussed in the post-commit comments, that transform might be too dangerous without this warning in place (and we might want to revert it anyway until this patch has had some time to bake in the wild).

Diff Detail

Event Timeline

spatel created this revision.Mar 9 2022, 9:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 9 2022, 9:44 AM
Herald added a subscriber: mcrosier. · View Herald Transcript
spatel requested review of this revision.Mar 9 2022, 9:44 AM

Thanks! Yeah, we need a warning like this one.

Some nits added.

clang/include/clang/Basic/DiagnosticSemaKinds.td
122

maybe even say why this is always false?

clang/test/Sema/floating-point-compare.c
26

// expected-warning {{result of floating-point comparison is always false}}

35

Same here.

spatel marked 3 inline comments as done.Mar 9 2022, 12:26 PM
spatel added inline comments.
clang/include/clang/Basic/DiagnosticSemaKinds.td
122

Sure. I'm not sure how wordy we want to be, but I can add the source type as a parameter, so that should make it clearer.

Then we would show something like this:

54222.c:4:12: warning: floating-point comparison is always false: constant cannot be represented exactly in type 'float' [-Wliteral-range]
  return f == 0.1;
spatel updated this revision to Diff 414185.Mar 9 2022, 12:28 PM
spatel marked an inline comment as done.

Patch updated:

  1. Improved warning message.
  2. Check warning string more exactly in test file.
xbolva00 added inline comments.Mar 9 2022, 12:36 PM
clang/include/clang/Basic/DiagnosticSemaKinds.td
122

Sounds good

spatel updated this revision to Diff 415478.Mar 15 2022, 9:40 AM

No code changes, just updated test comments.

This check seems a little narrow, but fine, I guess.

clang/lib/Sema/SemaChecking.cpp
11432

Fix comments?

11439

Maybe consider IgnoreParens().

11450

There's a helper for this pattern: SourceTy->getAs<BuiltinType>()

clang/test/Sema/floating-point-compare.c
26–36

Maybe also add a testcase with an explicit float->double cast?

spatel updated this revision to Diff 415517.Mar 15 2022, 11:25 AM
spatel marked 4 inline comments as done.

Patch updated:

  1. Updated function comment.
  2. Look through optional parentheses.
  3. Use getAs<BuiltinType>.
  4. Add tests with explicit casts, parens.
xbolva00 added inline comments.Mar 15 2022, 11:44 AM
clang/test/Sema/floating-point-compare.c
35

One test with macro?
#define CST 0.3

f == CST

spatel updated this revision to Diff 415543.Mar 15 2022, 12:37 PM
spatel marked an inline comment as done.

Added test with macro.

Thanks. One last thing - small info in Clang release notes?

Thanks. One last thing - small info in Clang release notes?

Sure - but if we're going to document this as a feature, I will add the != sibling warning now, so we don't advertise a half-implemented enhancement. :)

Yes, support for != would be fine.

spatel updated this revision to Diff 415802.Mar 16 2022, 6:19 AM
spatel edited the summary of this revision. (Show Details)

Patch updated:

  1. Implemented warning for != with selective text.
  2. Added tests for != warning.
  3. Mentioned improvement in release notes.

I don't think "floating-point comparison is only true for NaN" is accurate? It should just be "floating-point comparison is always true ", I think.

I don't think "floating-point comparison is only true for NaN" is accurate? It should just be "floating-point comparison is always true ", I think.

Ah, right. I mistakenly was thinking of C "!=" as "fcmp one" in IR, but the semantics are "fcmp une":
https://godbolt.org/z/TP7145Psv
https://alive2.llvm.org/ce/z/sbRVpA

spatel updated this revision to Diff 415949.Mar 16 2022, 1:06 PM

Updated code comments and warning message for != case; that's always true.

This revision is now accepted and ready to land.Mar 16 2022, 1:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 17 2022, 5:27 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
alexfh added a subscriber: alexfh.Mar 24 2022, 10:08 AM

What's the right fix for this warning, using a literal of the same floating point type? Did you consider adding a fixit hint to the diagnostic?

What's the right fix for this warning, using a literal of the same floating point type?

Probably? Depends on why you're trying to use equality on floating-point numbers; "x == 0.3" is inherently a bit suspicious.

Did you consider adding a fixit hint to the diagnostic?

A fixit to do what? Replacing the comparison with a literal "true"/"false" would probably be unwelcome. And I don't really want a "fixit" to change the meaning of well-defined code.