-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][bytecode] Create dummy pointers for non-reference DeclRefExprs #113202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Member
|
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) Changes... with non-constant initializers. Full diff: https://github.com/llvm/llvm-project/pull/113202.diff 5 Files Affected:
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index b960954d4754a8..59e09a44d747b9 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2371,9 +2371,9 @@ bool Compiler<Emitter>::VisitStringLiteral(const StringLiteral *E) {
template <class Emitter>
bool Compiler<Emitter>::VisitObjCStringLiteral(const ObjCStringLiteral *E) {
- if (std::optional<unsigned> I = P.getOrCreateDummy(E))
- return this->emitGetPtrGlobal(*I, E);
- return false;
+ if (DiscardResult)
+ return true;
+ return this->emitDummyPtr(E, E);
}
template <class Emitter>
@@ -3445,11 +3445,8 @@ bool Compiler<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
assert(RD);
// If the definiton of the result type is incomplete, just return a dummy.
// If (and when) that is read from, we will fail, but not now.
- if (!RD->isCompleteDefinition()) {
- if (std::optional<unsigned> I = P.getOrCreateDummy(GuidDecl))
- return this->emitGetPtrGlobal(*I, E);
- return false;
- }
+ if (!RD->isCompleteDefinition())
+ return this->emitDummyPtr(GuidDecl, E);
std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(GuidDecl);
if (!GlobalIndex)
@@ -3687,11 +3684,11 @@ bool Compiler<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
if (!E->isExpressibleAsConstantInitializer())
return this->discard(SubExpr) && this->emitInvalid(E);
- assert(classifyPrim(E) == PT_Ptr);
- if (std::optional<unsigned> I = P.getOrCreateDummy(E))
- return this->emitGetPtrGlobal(*I, E);
+ if (DiscardResult)
+ return true;
- return false;
+ assert(classifyPrim(E) == PT_Ptr);
+ return this->emitDummyPtr(E, E);
}
template <class Emitter>
@@ -4483,15 +4480,9 @@ bool Compiler<Emitter>::VisitBuiltinCallExpr(const CallExpr *E,
BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
BuiltinID == Builtin::BI__builtin_function_start) {
- if (std::optional<unsigned> GlobalOffset = P.getOrCreateDummy(E)) {
- if (!this->emitGetPtrGlobal(*GlobalOffset, E))
- return false;
-
- if (PrimType PT = classifyPrim(E); PT != PT_Ptr && isPtrType(PT))
- return this->emitDecayPtr(PT_Ptr, PT, E);
+ if (DiscardResult)
return true;
- }
- return false;
+ return this->emitDummyPtr(E, E);
}
QualType ReturnType = E->getType();
@@ -6097,6 +6088,10 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
if (VD->evaluateValue())
return revisit(VD);
+
+ if (!D->getType()->isReferenceType())
+ return this->emitDummyPtr(D, E);
+
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
/*InitializerFailed=*/true, E);
}
@@ -6109,23 +6104,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
}
}
- if (std::optional<unsigned> I = P.getOrCreateDummy(D)) {
- if (!this->emitGetPtrGlobal(*I, E))
- return false;
- if (E->getType()->isVoidType())
- return true;
- // Convert the dummy pointer to another pointer type if we have to.
- if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
- if (isPtrType(PT))
- return this->emitDecayPtr(PT_Ptr, PT, E);
- return false;
- }
- return true;
- }
-
- if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- return this->emitInvalidDeclRef(DRE, /*InitializerFailed=*/false, E);
- return false;
+ return this->emitDummyPtr(D, E);
}
template <class Emitter>
@@ -6428,6 +6407,29 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
return this->emitRecordDestruction(Desc->ElemRecord, Loc);
}
+/// Create a dummy pointer for the given decl (or expr) and
+/// push a pointer to it on the stack.
+template <class Emitter>
+bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
+ assert(!DiscardResult && "Should've been checked before");
+
+ unsigned DummyID = P.getOrCreateDummy(D);
+
+ if (!this->emitGetPtrGlobal(DummyID, E))
+ return false;
+ if (E->getType()->isVoidType())
+ return true;
+
+ // Convert the dummy pointer to another pointer type if we have to.
+ if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
+ if (isPtrType(PT))
+ return this->emitDecayPtr(PT_Ptr, PT, E);
+ return false;
+ }
+
+ return true;
+}
+
namespace clang {
namespace interp {
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 4253e7b3248c9f..5627d5071e810a 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -370,6 +370,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
const BinaryOperator *E);
bool emitRecordDestruction(const Record *R, SourceInfo Loc);
bool emitDestruction(const Descriptor *Desc, SourceInfo Loc);
+ bool emitDummyPtr(const DeclTy &D, const Expr *E);
unsigned collectBaseOffset(const QualType BaseType,
const QualType DerivedType);
bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD);
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index cd2665f755d7cb..0da518ec92afae 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -147,7 +147,7 @@ std::optional<unsigned> Program::getOrCreateGlobal(const ValueDecl *VD,
return std::nullopt;
}
-std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) {
+unsigned Program::getOrCreateDummy(const DeclTy &D) {
assert(D);
// Dedup blocks since they are immutable and pointers cannot be compared.
if (auto It = DummyVariables.find(D.getOpaqueValue());
diff --git a/clang/lib/AST/ByteCode/Program.h b/clang/lib/AST/ByteCode/Program.h
index f676672fb7ced5..9aabe67b550ec7 100644
--- a/clang/lib/AST/ByteCode/Program.h
+++ b/clang/lib/AST/ByteCode/Program.h
@@ -85,7 +85,7 @@ class Program final {
const Expr *Init = nullptr);
/// Returns or creates a dummy value for unknown declarations.
- std::optional<unsigned> getOrCreateDummy(const DeclTy &D);
+ unsigned getOrCreateDummy(const DeclTy &D);
/// Creates a global and returns its index.
std::optional<unsigned> createGlobal(const ValueDecl *VD, const Expr *Init);
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index 215f26bd5da8ea..76ac33047138d4 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1661,3 +1661,19 @@ namespace NullptrUpcast {
constexpr A &ra = *nb; // both-error {{constant expression}} \
// both-note {{cannot access base class of null pointer}}
}
+
+namespace NonConst {
+ template <int I>
+ struct S {
+ static constexpr int Size = I;
+ constexpr int getSize() const { return I; }
+ explicit S(int a) {}
+ };
+
+ void func() {
+
+ int a,b ;
+ const S<10> s{a};
+ static_assert(s.getSize() == 10);
+ }
+}
|
... with non-constant initializers.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
clang:frontend
Language frontend issues, e.g. anything involving "Sema"
clang
Clang issues not falling into any other category
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
... with non-constant initializers.