llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
Just like we do with the first parameter of a regular `__builtin_object_size`
call.
This still doesn't fix the bigger bos test cases since e.g.
```c++
int NoViableOverloadObjectSize3(void *const p PS(3))
__attribute__((overloadable)) {
return __builtin_object_size(p, 3);
}
void test4(struct Foo *t) {
gi = NoViableOverloadObjectSize3(&t[1].t[1]);
}
```
is still broken because we don't have special handling for the `&t[1].t[1]`
handling here and we can't usually access a one-past-end pointer.
---
Full diff: https://github.com/llvm/llvm-project/pull/196010.diff
7 Files Affected:
- (modified) clang/lib/AST/ByteCode/ByteCodeEmitter.h (+1)
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+9)
- (modified) clang/lib/AST/ByteCode/Compiler.h (+1)
- (modified) clang/lib/AST/ByteCode/Context.cpp (+1-1)
- (modified) clang/lib/AST/ByteCode/EvalEmitter.cpp (+15-2)
- (modified) clang/lib/AST/ByteCode/EvalEmitter.h (+2)
- (modified) clang/test/AST/ByteCode/builtin-object-size-codegen.c (+6)
``````````diff
diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.h
b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
index 102ce939c6717..e3aa3c940de47 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.h
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
@@ -46,6 +46,7 @@ class ByteCodeEmitter {
/// Methods implemented by the compiler.
virtual bool visitFunc(const FunctionDecl *E) = 0;
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
+ virtual bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) = 0;
virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) = 0;
virtual bool visit(const Expr *E) = 0;
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp
b/clang/lib/AST/ByteCode/Compiler.cpp
index 11c5478a5c748..666de65732d2e 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5148,6 +5148,15 @@ bool Compiler<Emitter>::visitExpr(const Expr *E, bool
DestroyToplevelScope) {
return maybeDestroyLocals() && false;
}
+template <class Emitter>
+bool Compiler<Emitter>::visitLValueExpr(const Expr *E,
+ bool DestroyToplevelScope) {
+ OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
+ /*NewInitializing=*/false, /*ToLValue=*/true);
+
+ return this->visitExpr(E, DestroyToplevelScope);
+}
+
template <class Emitter>
VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD) {
diff --git a/clang/lib/AST/ByteCode/Compiler.h
b/clang/lib/AST/ByteCode/Compiler.h
index de6ea524897a0..ff5d0c05fe14b 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -253,6 +253,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>,
bool>,
protected:
bool visitStmt(const Stmt *S);
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override;
+ bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override;
bool visitFunc(const FunctionDecl *F) override;
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
diff --git a/clang/lib/AST/ByteCode/Context.cpp
b/clang/lib/AST/ByteCode/Context.cpp
index 3a8a50f2aeb53..35959715946c3 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -345,7 +345,7 @@ Context::tryEvaluateObjectSize(State &Parent, const Expr
*E, unsigned Kind) {
std::optional<uint64_t> Result;
- auto PtrRes = C.interpretAsPointer(E, [&](const Pointer &Ptr) {
+ auto PtrRes = C.interpretAsLValuePointer(E, [&](const Pointer &Ptr) {
const Descriptor *DeclDesc = Ptr.getDeclDesc();
if (!DeclDesc)
return false;
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp
b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index 319ef7edd57b9..d3acaa406af51 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -75,14 +75,13 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl
*VD, const Expr *Init,
EvaluationResult EvalEmitter::interpretAsPointer(const Expr *E,
PtrCallback PtrCB) {
-
S.setEvalLocation(E->getExprLoc());
this->ConvertResultToRValue = false;
this->CheckFullyInitialized = false;
this->PtrCB = PtrCB;
EvalResult.setSource(E);
- if (!this->visitExpr(E, /*DestroyToplevelScope=*/true)) {
+ if (!this->visitExpr(E, true)) {
// EvalResult may already have a result set, but something failed
// after that (e.g. evaluating destructors).
EvalResult.setInvalid();
@@ -91,6 +90,20 @@ EvaluationResult EvalEmitter::interpretAsPointer(const Expr
*E,
return std::move(this->EvalResult);
}
+EvaluationResult EvalEmitter::interpretAsLValuePointer(const Expr *E,
+ PtrCallback PtrCB) {
+ S.setEvalLocation(E->getExprLoc());
+ this->ConvertResultToRValue = false;
+ this->CheckFullyInitialized = false;
+ this->PtrCB = PtrCB;
+ EvalResult.setSource(E);
+
+ if (!this->visitLValueExpr(E, true))
+ EvalResult.setInvalid();
+
+ return std::move(this->EvalResult);
+}
+
bool EvalEmitter::interpretCall(const FunctionDecl *FD, const Expr *E) {
// Add parameters to the parameter map. The values in the ParamOffset don't
// matter in this case as reading from them can't ever work.
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h
b/clang/lib/AST/ByteCode/EvalEmitter.h
index 8f6da7aef422a..ce5825eef3607 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.h
+++ b/clang/lib/AST/ByteCode/EvalEmitter.h
@@ -42,6 +42,7 @@ class EvalEmitter : public SourceMapper {
bool CheckFullyInitialized);
/// Interpret the given Expr to a Pointer.
EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB);
+ EvaluationResult interpretAsLValuePointer(const Expr *E, PtrCallback PtrCB);
/// Interpret the given expression as if it was in the body of the given
/// function, i.e. the parameters of the function are available for use.
bool interpretCall(const FunctionDecl *FD, const Expr *E);
@@ -61,6 +62,7 @@ class EvalEmitter : public SourceMapper {
/// Methods implemented by the compiler.
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
+ virtual bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) = 0;
virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) = 0;
virtual bool visitFunc(const FunctionDecl *F) = 0;
diff --git a/clang/test/AST/ByteCode/builtin-object-size-codegen.c
b/clang/test/AST/ByteCode/builtin-object-size-codegen.c
index 6aa0485bd65ad..1b2561a89ebba 100644
--- a/clang/test/AST/ByteCode/builtin-object-size-codegen.c
+++ b/clang/test/AST/ByteCode/builtin-object-size-codegen.c
@@ -35,6 +35,12 @@
// gi = ObjectSize2(&t[1].t[1]);
}
+void foo2(struct Foo *t) {
+ // CHECK: call i32 @ObjectSize3(ptr noundef %{{.*}}, i64 noundef 36)
+ ObjectSize3(&t->t[1]);
+}
+
+
/// Used to crash due to the void-typed ArraySubscriptExpr.
void foo(void *p) {
int i = __builtin_object_size(&p[2], 3);
``````````
</details>
https://github.com/llvm/llvm-project/pull/196010
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits