Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clang: constexpr does not honor -fwrapv, leading to compilation error #59195

Closed
markus-oberhumer opened this issue Nov 24, 2022 · 9 comments
Closed
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" invalid Resolved as invalid, i.e. not a bug

Comments

@markus-oberhumer
Copy link

markus-oberhumer commented Nov 24, 2022

Godbolt link: https://godbolt.org/z/8KhvbcWr6

Reproducible with clang-trunk

$ clang++ -fwrapv -Wno-integer-overflow -c test.cpp
test.cpp:15:16: error: constexpr variable 'b2' must be initialized by a constant expression
$ cat test.cpp
// compile with: clang++ -fwrapv -Wno-integer-overflow -c test.cpp
//
// extra rant: -Wno-integer-overflow should not be needed here!

#include <limits.h>

#define wrap_inc(x)     ((x) + 1 < (x))

constexpr int int_max = INT_MAX;

bool b0 = wrap_inc(int_max);
const bool b1 = wrap_inc(int_max);

// error: constexpr variable 'b2' must be initialized by a constant expression
constexpr bool b2 = wrap_inc(int_max);
@shafik
Copy link
Collaborator

shafik commented Nov 24, 2022

We seem to be consistent with gcc in most cases although the bool case stands out, I believe that is a gcc bug b/c that case should be treated the same way, see: https://godbolt.org/z/ad3391Eh3

I believe command line options should not modify whether an expression is considered well-formed in a constant expression or not b/c this has wider impacts on portability due to use in templates and other scenarios that required constant expression such as support for variable length arrays as an extension. Although I will leave it open to allow for more feedback if others want to weigh in.

@markus-oberhumer
Copy link
Author

Yes, gcc has a similar but not identical problem/view. Reported as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107861

@jwakely
Copy link
Contributor

jwakely commented Nov 24, 2022

I believe command line options should not modify whether an expression is considered well-formed in a constant expression or not b/c this has wider impacts on portability

100% agreed

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Nov 25, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 25, 2022

@llvm/issue-subscribers-clang-frontend

@markus-oberhumer
Copy link
Author

I believe command line options should not modify whether an expression is considered well-formed in a constant expression or not b/c this has wider impacts on portability

100% agreed

I get your point, but please note that we already have such command line options.

godbolt link: https://godbolt.org/z/5EvdhWha8

// -fsigned-char:   error: constexpr variable 'dummy' must be initialized by a constant expression
// -funsigned-char: valid

constexpr int dummy = (('\377' > 0) -1) << (sizeof(int) * 8 - 1);



@jwakely
Copy link
Contributor

jwakely commented Nov 25, 2022

Not the same. The standard says it's unspecified whether char is signed or unsigned. It doesn't say it's unspecified whether INT_MAX+1 is valid.

@markus-oberhumer
Copy link
Author

So you're saying that int_max + 1 is invalid per definition, even if my C++ compiler explicitly implements wrapping signed integers?

@shafik
Copy link
Collaborator

shafik commented Nov 26, 2022

Unspecified behavior still results in a well-formed program:

behavior, for a well-formed program construct and correct data, that depends on the implementation

Even though unspecified behavior is well-formed it is not portable and developers need to be aware of that and design accordingly.

Undefined behavior is never well-formed. It is a runtime behavior and even though we have command line options to define the behavior at runtime undefined behavior is not allowed in a constant expression:

An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:

and includes the following bullet:

an operation that would have undefined behavior as specified in [intro] through [cpp], excluding [dcl.attr.assume];

@markus-oberhumer
Copy link
Author

@shafik @jwakely Many thanks for your detailed feedback, so I'd guess this issue can be closed as invalid.

@EugeneZelenko EugeneZelenko closed this as not planned Won't fix, can't repro, duplicate, stale Nov 27, 2022
@EugeneZelenko EugeneZelenko added the invalid Resolved as invalid, i.e. not a bug label Nov 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" invalid Resolved as invalid, i.e. not a bug
Projects
None yet
Development

No branches or pull requests

5 participants