[clang] [clang][bytecode] Fix a crash with covariant return types (PR #201354)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
Changes
`Context::collectBaseOffset()` will assert if the passed-in classes are the
same.
---
Full diff: https://github.com/llvm/llvm-project/pull/201354.diff
3 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+6)
- (modified) clang/lib/AST/ByteCode/Pointer.h (+2)
- (modified) clang/test/AST/ByteCode/cxx20.cpp (+15)
``diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp
b/clang/lib/AST/ByteCode/Interp.cpp
index 6bcebf3ee892b..092c054857aee 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2000,6 +2000,12 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const
Function *Func,
Overrider->getReturnType()->getPointeeType();
QualType InitialPointeeType =
InitialFunction->getReturnType()->getPointeeType();
+
+// Nothing to do if the types already match.
+if (S.getASTContext().hasSimilarType(InitialPointeeType,
+ OverriderPointeeType))
+ return true;
+
// We've called Overrider above, but calling code expects us to return what
// InitialFunction returned. According to the rules for covariant return
// types, what InitialFunction returns needs to be a base class of what
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index b48f880d8796b..a77918f667fd3 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -931,6 +931,8 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const Pointer &P) {
OS << " dummy";
if (!P.isLive())
OS << " dead";
+ if (P.isBaseClass())
+OS << " base-class";
return OS;
}
diff --git a/clang/test/AST/ByteCode/cxx20.cpp
b/clang/test/AST/ByteCode/cxx20.cpp
index d3e6265a9cbe7..3f8278643a50f 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -1365,5 +1365,20 @@ namespace IndirectFieldInitializer {
constexpr A() {}
};
static_assert(A().x == 3, "");
+}
+namespace Covariant {
+ struct A {
+int a;
+constexpr virtual const A* getA() const = 0;
+ };
+ struct B { int b; };
+
+ struct C: A, B {
+constexpr const C* getA() const override {
+ return this;
+}
+ };
+ constexpr C c{};
+ static_assert(c.getA() == &c);
}
``
https://github.com/llvm/llvm-project/pull/201354
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][bytecode] Fix a crash with covariant return types (PR #201354)
https://github.com/tbaederr created
https://github.com/llvm/llvm-project/pull/201354
`Context::collectBaseOffset()` will assert if the passed-in classes are the
same.
>From 17444bc25f8d1bb449d303eeb016ec1754625654 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?=
Date: Wed, 3 Jun 2026 15:11:15 +0200
Subject: [PATCH] [clang][bytecode] Fix a crash with covariant return types
`Context::collectBaseOffset()` will assert if the passed-in classes are
the same.
---
clang/lib/AST/ByteCode/Interp.cpp | 6 ++
clang/lib/AST/ByteCode/Pointer.h | 2 ++
clang/test/AST/ByteCode/cxx20.cpp | 15 +++
3 files changed, 23 insertions(+)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp
b/clang/lib/AST/ByteCode/Interp.cpp
index 6bcebf3ee892b..092c054857aee 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2000,6 +2000,12 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const
Function *Func,
Overrider->getReturnType()->getPointeeType();
QualType InitialPointeeType =
InitialFunction->getReturnType()->getPointeeType();
+
+// Nothing to do if the types already match.
+if (S.getASTContext().hasSimilarType(InitialPointeeType,
+ OverriderPointeeType))
+ return true;
+
// We've called Overrider above, but calling code expects us to return what
// InitialFunction returned. According to the rules for covariant return
// types, what InitialFunction returns needs to be a base class of what
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index b48f880d8796b..a77918f667fd3 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -931,6 +931,8 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const Pointer &P) {
OS << " dummy";
if (!P.isLive())
OS << " dead";
+ if (P.isBaseClass())
+OS << " base-class";
return OS;
}
diff --git a/clang/test/AST/ByteCode/cxx20.cpp
b/clang/test/AST/ByteCode/cxx20.cpp
index d3e6265a9cbe7..3f8278643a50f 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -1365,5 +1365,20 @@ namespace IndirectFieldInitializer {
constexpr A() {}
};
static_assert(A().x == 3, "");
+}
+namespace Covariant {
+ struct A {
+int a;
+constexpr virtual const A* getA() const = 0;
+ };
+ struct B { int b; };
+
+ struct C: A, B {
+constexpr const C* getA() const override {
+ return this;
+}
+ };
+ constexpr C c{};
+ static_assert(c.getA() == &c);
}
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
