aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Pointer.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-04-24 17:04:36 +0200
committerGitHub <noreply@github.com>2025-04-24 17:04:36 +0200
commit9ae7aa79b1e151c3af12b9ffec0e2fdeacde5cc9 (patch)
treed75204057903bf68771d58c2a120571df1d71bf6 /clang/lib/AST/ByteCode/Pointer.cpp
parentd859cb68836191cfa469d0c951134b53ee31298e (diff)
downloadllvm-9ae7aa79b1e151c3af12b9ffec0e2fdeacde5cc9.zip
llvm-9ae7aa79b1e151c3af12b9ffec0e2fdeacde5cc9.tar.gz
llvm-9ae7aa79b1e151c3af12b9ffec0e2fdeacde5cc9.tar.bz2
[clang][bytecode] Diagnose comparing pointers to fields... (#137159)
... with different access specifiers.
Diffstat (limited to 'clang/lib/AST/ByteCode/Pointer.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Pointer.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 059503c..6c2566b 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -571,6 +571,48 @@ bool Pointer::pointsToLiteral() const {
return E && !isa<MaterializeTemporaryExpr, StringLiteral>(E);
}
+std::optional<std::pair<Pointer, Pointer>>
+Pointer::computeSplitPoint(const Pointer &A, const Pointer &B) {
+ if (!A.isBlockPointer() || !B.isBlockPointer())
+ return std::nullopt;
+
+ if (A.asBlockPointer().Pointee != B.asBlockPointer().Pointee)
+ return std::nullopt;
+ if (A.isRoot() && B.isRoot())
+ return std::nullopt;
+
+ if (A == B)
+ return std::make_pair(A, B);
+
+ auto getBase = [](const Pointer &P) -> Pointer {
+ if (P.isArrayElement())
+ return P.expand().getArray();
+ return P.getBase();
+ };
+
+ Pointer IterA = A;
+ Pointer IterB = B;
+ Pointer CurA = IterA;
+ Pointer CurB = IterB;
+ for (;;) {
+ if (IterA.asBlockPointer().Base > IterB.asBlockPointer().Base) {
+ CurA = IterA;
+ IterA = getBase(IterA);
+ } else {
+ CurB = IterB;
+ IterB = getBase(IterB);
+ }
+
+ if (IterA == IterB)
+ return std::make_pair(CurA, CurB);
+
+ if (IterA.isRoot() && IterB.isRoot())
+ return std::nullopt;
+ }
+
+ llvm_unreachable("The loop above should've returned.");
+}
+
std::optional<APValue> Pointer::toRValue(const Context &Ctx,
QualType ResultType) const {
const ASTContext &ASTCtx = Ctx.getASTContext();