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]; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits