This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Add machinery to catch overflow in unary minus outside of a constant expression context
ClosedPublic

Authored by shafik on Jan 29 2023, 10:14 PM.

Details

Summary

We provide several diagnostics for various undefined behaviors due to signed integer overflow outside of a constant expression context. We were missing the machinery to catch overflows due to unary minus.

Fixes: https://github.com/llvm/llvm-project/issues/31643

Diff Detail

Event Timeline

shafik created this revision.Jan 29 2023, 10:14 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 29 2023, 10:14 PM
shafik requested review of this revision.Jan 29 2023, 10:14 PM
aaron.ballman accepted this revision.Jan 30 2023, 11:41 AM

LGTM, though needs a release note.

clang/lib/AST/ExprConstant.cpp
13503–13513
This revision is now accepted and ready to land.Jan 30 2023, 11:41 AM
shafik updated this revision to Diff 493641.Jan 31 2023, 8:51 AM
shafik marked an inline comment as done.
  • Add release note.
This revision was landed with ongoing or failed builds.Jan 31 2023, 9:35 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJan 31 2023, 9:35 AM
eaeltsin added a subscriber: eaeltsin.EditedFeb 6 2023, 1:52 PM

The warning now fires even if overflow is prevented with if constexpr:

if constexpr (width <= 64) {
  if constexpr (width == 64) {
    return 1;
  }
  return -static_cast<int64_t>(uint64_t{1} << (width - 1));
}

https://godbolt.org/z/M3xdcKd3M

shafik added a comment.Feb 6 2023, 8:53 PM

The warning now fires even if overflow is prevented with if constexpr:

if constexpr (width <= 64) {
  if constexpr (width == 64) {
    return 1;
  }
  return -static_cast<int64_t>(uint64_t{1} << (width - 1));
}

https://godbolt.org/z/M3xdcKd3M

I believe this is due to issue: https://github.com/llvm/llvm-project/issues/59448

The warning now fires even if overflow is prevented with if constexpr:

if constexpr (width <= 64) {
  if constexpr (width == 64) {
    return 1;
  }
  return -static_cast<int64_t>(uint64_t{1} << (width - 1));
}

https://godbolt.org/z/M3xdcKd3M

For reference, actually placing the second return into an else block (thus making it a discarded statement) does suppress the diagnostic:
https://godbolt.org/z/Kb6Md5PrK

I also question the focus on if constexpr. Replacing with if (true) { return 1; } should be as effective in the non-else-block case in suppressing the warning in terms of QoI.