[clang] d957da8 - [clang][Interp] Allow taking the address of a non-const global reference
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 29 10:55:48 PDT 2024
Author: Timm Bäder
Date: 2024-06-29T19:55:29+02:00
New Revision: d957da83791930a3c23f4f936ca7c7644c4b07a4
URL: https://github.com/llvm/llvm-project/commit/d957da83791930a3c23f4f936ca7c7644c4b07a4
DIFF: https://github.com/llvm/llvm-project/commit/d957da83791930a3c23f4f936ca7c7644c4b07a4.diff
LOG: [clang][Interp] Allow taking the address of a non-const global reference
This is not a read, but the GetGlobal op before failed if the reference
we were taking a pointer of was non-const. Use GetGlobalUnchecked
instead.
Added:
Modified:
clang/lib/AST/Interp/Compiler.cpp
clang/lib/AST/Interp/Interp.h
clang/test/AST/Interp/references.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index e21e2c0eb8b6a..8b6f7f644a778 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -4906,8 +4906,11 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
return this->emitGetLocal(PT_Ptr, Offset, E);
return this->emitGetPtrLocal(Offset, E);
} else if (auto GlobalIndex = P.getGlobal(D)) {
- if (IsReference)
- return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
+ if (IsReference) {
+ if (!Ctx.getLangOpts().CPlusPlus11)
+ return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
+ return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
+ }
return this->emitGetPtrGlobal(*GlobalIndex, E);
} else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 916d268aa4f09..6c9246f692204 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1255,7 +1255,10 @@ bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
/// Same as GetGlobal, but without the checks.
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I) {
- auto *B = S.P.getGlobal(I);
+ const Pointer &Ptr = S.P.getPtrGlobal(I);
+ if (!Ptr.isInitialized())
+ return false;
+ const Block *B = S.P.getGlobal(I);
S.Stk.push<T>(B->deref<T>());
return true;
}
diff --git a/clang/test/AST/Interp/references.cpp b/clang/test/AST/Interp/references.cpp
index efb756545b4aa..9a790dc75d730 100644
--- a/clang/test/AST/Interp/references.cpp
+++ b/clang/test/AST/Interp/references.cpp
@@ -130,3 +130,8 @@ const char (&nonextended_string_ref)[3] = {"hi"};
static_assert(nonextended_string_ref[0] == 'h', "");
static_assert(nonextended_string_ref[1] == 'i', "");
static_assert(nonextended_string_ref[2] == '\0', "");
+
+/// This isa non-constant context. Reading A is not allowed,
+/// but taking its address is.
+int &&A = 12;
+int arr[!&A];
More information about the cfe-commits
mailing list