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

Reply via email to