diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-08-06 16:49:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-06 16:49:00 +0200 |
commit | 8704ca0fb8fb3c659a4e98e9362cd56d453dcb4b (patch) | |
tree | c2e49d091c10143c25697e1e36d5950c600f30da /clang/lib | |
parent | 75838b818bdbc14fc41f901b4e60821647009cf3 (diff) | |
download | llvm-8704ca0fb8fb3c659a4e98e9362cd56d453dcb4b.zip llvm-8704ca0fb8fb3c659a4e98e9362cd56d453dcb4b.tar.gz llvm-8704ca0fb8fb3c659a4e98e9362cd56d453dcb4b.tar.bz2 |
[clang][ExprConst] Consider integer pointers of value 0 nullptr (#150164)
When casting a 0 to a pointer type, the IsNullPtr flag was always set to
false, leading to weird results like a pointer with value 0 that isn't a
null pointer.
This caused
```c++
struct B { const int *p;};
template<B> void f() {}
template void f<B{nullptr}>();
template void f<B{fold(reinterpret_cast<int*>(0))}>();
```
to be valid code, since nullptr and (int*)0 aren't equal. This seems
weird and GCC doesn't behave like this.
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 34af9cc..3679327 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9860,11 +9860,15 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { if (Value.isInt()) { unsigned Size = Info.Ctx.getTypeSize(E->getType()); uint64_t N = Value.getInt().extOrTrunc(Size).getZExtValue(); - Result.Base = (Expr*)nullptr; - Result.InvalidBase = false; - Result.Offset = CharUnits::fromQuantity(N); - Result.Designator.setInvalid(); - Result.IsNullPtr = false; + if (N == Info.Ctx.getTargetNullPointerValue(E->getType())) { + Result.setNull(Info.Ctx, E->getType()); + } else { + Result.Base = (Expr *)nullptr; + Result.InvalidBase = false; + Result.Offset = CharUnits::fromQuantity(N); + Result.Designator.setInvalid(); + Result.IsNullPtr = false; + } return true; } else { // In rare instances, the value isn't an lvalue. |