This is an archive of the discontinued LLVM Phabricator instance.

[clang][Sema] Skip checking int expressions for overflow in constexpr functions
AbandonedPublic

Authored by tbaeder on Nov 18 2022, 1:16 AM.

Details

Reviewers
None
Group Reviewers
Restricted Project
Summary

I'm not 100% sure if this is crazy or not, but it doesn't even seem to break any existing test cases.

We evaluate all integer expressions for overflows and diagnose them if possible. However, in the case of a constexpr function, we will evaluate the function (and all expressions it contains) anyway after parsing it, which will check for overflow again, so the previous checking is unnecessary.

I checked that not calling CheckForIntOverflow() at all breaks tests (it does).

Diff Detail

Event Timeline

tbaeder created this revision.Nov 18 2022, 1:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 18 2022, 1:16 AM
tbaeder requested review of this revision.Nov 18 2022, 1:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 18 2022, 1:16 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
tbaeder updated this revision to Diff 476391.Nov 18 2022, 2:28 AM
shafik added a subscriber: shafik.Nov 28 2022, 7:57 PM

We may not have good code coverage, what about a case like this:

constexpr void f() {
    int arr[10]{};
    arr[1024*1024*1024*1204];
}

do you still obtain:

 error: constexpr function never produces a constant expression [-Winvalid-constexpr]
constexpr void f() {
               ^

godbolt: https://godbolt.org/z/5T5Gn5rxq

Output for that test case is:

./array.cpp:1:16: error: constexpr function never produces a constant expression [-Winvalid-constexpr]
constexpr void f() {
               ^
./array.cpp:3:23: note: value 1292785156096 is outside the range of representable values of type 'int'
    arr[1024*1024*1024*1204];
                      ^
./array.cpp:3:28: warning: expression result unused [-Wunused-value]
    arr[1024*1024*1024*1204];
    ~~~ ~~~~~~~~~~~~~~~~~~~^
1 warning and 1 error generated.

The first overflow warning is missing. That seems to be new though, I don't get that warning with clang 14 either.

Output for that test case is:

./array.cpp:1:16: error: constexpr function never produces a constant expression [-Winvalid-constexpr]
constexpr void f() {
               ^
./array.cpp:3:23: note: value 1292785156096 is outside the range of representable values of type 'int'
    arr[1024*1024*1024*1204];
                      ^
./array.cpp:3:28: warning: expression result unused [-Wunused-value]
    arr[1024*1024*1024*1204];
    ~~~ ~~~~~~~~~~~~~~~~~~~^
1 warning and 1 error generated.

The first overflow warning is missing. That seems to be new though, I don't get that warning with clang 14 either.

The downside to losing that warning is that passing -Wno-invalid-constexpr will lose the diagnostic entirely, which seems like a regression.

clang/include/clang/Sema/Sema.h
3514–3517

You should add some documentation comments to the function.

One slight worry I have here is with dependent (perhaps special) member functions; is this function meant to answer "is this function callable in a constexpr context" or is it meant to answer "did the user specify this as a constexpr function"?

e.g.,

template <int N>
constexpr int func(int Val) { return Val / N; } // Not yet instantiated.
tbaeder abandoned this revision.Jul 28 2023, 12:24 AM