Issue |
142707
|
Summary |
clang evaluates is_constant_evaluated incorrectly with narrowing conversion
|
Labels |
clang
|
Assignees |
|
Reporter |
efriedma-quic
|
Consider the following example:
```
#include <type_traits>
struct X { unsigned u; };
void f(X x);
void g(int a) {
f({0xFFFFFFFFLL + std::is_constant_evaluated()});
}
```
The standard says the conversion is narrowing if "the source is a constant _expression_ whose value after integral promotions will fit into the target type". gcc correctly rejects because of this: it treats the _expression_ as a constant _expression_, then it fails to narrow. clang incorrectly accepts because isCXX11ConstantExpr() doesn't treat the evaluation as a constant context.
We have to be a little careful here... consider the following variant:
```
#include <type_traits>
struct X { unsigned u; };
void f(X x);
void g(int a) {
f({0x100000000LL - std::is_constant_evaluated()});
}
```
clang incorrectly rejects. gcc miscompiles: it checks the narrowing in a constant context, but then doesn't evaluate the actual _expression_ in a constant context, so the integer overflows to 0.
(I don't expect anyone to intentionally do this... wrote some synthetic testcases while looking at isCXX11ConstantExpr() for other reasons.)
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs