Skip to content

Conversation

@tbaederr
Copy link
Contributor

We used to do this the other way around to work around an awkwardness with CheckStore, namely that we shouldn't check pointers for being activated when activating them.

Add a parameter to CheckStore instead and call CheckStore() before activating and initializing the pointers in the respective opcode implementations.

Fixes #164975

We used to do this the other way around to work around an awkwardness with CheckStore, namely that we shouldn't check pointers for being activated when activating them. Add a parameter to CheckStore instead and call CheckStore() _before_ activating and initializing the pointers in the respective opcode implementations. Fixes llvm#164975
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:bytecode Issues for the clang bytecode constexpr interpreter labels Oct 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

We used to do this the other way around to work around an awkwardness with CheckStore, namely that we shouldn't check pointers for being activated when activating them.

Add a parameter to CheckStore instead and call CheckStore() before activating and initializing the pointers in the respective opcode implementations.

Fixes #164975


Full diff: https://github.com/llvm/llvm-project/pull/165235.diff

3 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+3-2)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+13-11)
  • (modified) clang/test/AST/ByteCode/unions.cpp (+9)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 910868b27f48e..0e2ba3c5e82d2 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -870,7 +870,8 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return true; } -bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { +bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + bool WillBeActivated) { if (!Ptr.isBlockPointer() || Ptr.isZero()) return false; @@ -885,7 +886,7 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return false; if (!CheckRange(S, OpPC, Ptr, AK_Assign)) return false; - if (!CheckActive(S, OpPC, Ptr, AK_Assign)) + if (!WillBeActivated && !CheckActive(S, OpPC, Ptr, AK_Assign)) return false; if (!CheckGlobal(S, OpPC, Ptr)) return false; diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 89f6fbefb1907..43c3ab76b15f9 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -75,7 +75,8 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B); bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B); /// Checks if a value can be stored in a block. -bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr); +bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + bool WillBeActivated = false); /// Checks if a value can be initialized. bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr); @@ -1977,13 +1978,12 @@ bool StoreActivate(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.peek<Pointer>(); + if (!CheckStore(S, OpPC, Ptr, /*WilLBeActivated=*/true)) + return false; if (Ptr.canBeInitialized()) { Ptr.initialize(); Ptr.activate(); } - - if (!CheckStore(S, OpPC, Ptr)) - return false; Ptr.deref<T>() = Value; return true; } @@ -1993,12 +1993,12 @@ bool StoreActivatePop(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckStore(S, OpPC, Ptr, /*WilLBeActivated=*/true)) + return false; if (Ptr.canBeInitialized()) { Ptr.initialize(); Ptr.activate(); } - if (!CheckStore(S, OpPC, Ptr)) - return false; Ptr.deref<T>() = Value; return true; } @@ -2007,7 +2007,8 @@ template <PrimType Name, class T = typename PrimConv<Name>::T> bool StoreBitField(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.peek<Pointer>(); - if (!CheckStore(S, OpPC, Ptr)) + + if (!CheckStore(S, OpPC, Ptr, /*WilLBeActivated=*/true)) return false; if (Ptr.canBeInitialized()) Ptr.initialize(); @@ -2037,12 +2038,13 @@ template <PrimType Name, class T = typename PrimConv<Name>::T> bool StoreBitFieldActivate(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.peek<Pointer>(); + + if (!CheckStore(S, OpPC, Ptr, /*WilLBeActivated=*/true)) + return false; if (Ptr.canBeInitialized()) { Ptr.initialize(); Ptr.activate(); } - if (!CheckStore(S, OpPC, Ptr)) - return false; if (const auto *FD = Ptr.getField()) Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue()); else @@ -2055,12 +2057,12 @@ bool StoreBitFieldActivatePop(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckStore(S, OpPC, Ptr, /*WillBeActivated=*/true)) + return false; if (Ptr.canBeInitialized()) { Ptr.initialize(); Ptr.activate(); } - if (!CheckStore(S, OpPC, Ptr)) - return false; if (const auto *FD = Ptr.getField()) Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue()); else diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp index 6bccbda23f468..414070417a02a 100644 --- a/clang/test/AST/ByteCode/unions.cpp +++ b/clang/test/AST/ByteCode/unions.cpp @@ -977,4 +977,13 @@ namespace UnionMemberOnePastEnd { } static_assert(!b()); } + +namespace ActicvateInvalidPtr { + constexpr void bar() { // both-error {{never produces a constant expression}} + union { + int a[1]; + } foo; + foo.a[1] = 0; // both-note {{assignment to dereferenced one-past-the-end pointer}} + } +} #endif 
@tbaederr tbaederr merged commit d7e40f3 into llvm:main Oct 27, 2025
14 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 27, 2025

LLVM Buildbot has detected a new failure on builder clang-aarch64-quick running on linaro-clang-aarch64-quick while building clang at step 5 "ninja check 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/24576

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure) ******************** TEST 'Clangd Unit Tests :: ./ClangdTests/112/335' FAILED ******************** Script(shard): -- GTEST_OUTPUT=json:/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests-Clangd Unit Tests-315154-112-335.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=335 GTEST_SHARD_INDEX=112 /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests -- Note: This is test shard 113 of 335. [==========] Running 4 tests from 4 test suites. [----------] Global test environment set-up. [----------] 1 test from CompletionTest [ RUN ] CompletionTest.DynamicIndexMultiFile ASTWorker building file /clangd-test/foo.cpp version null with command [/clangd-test] clang -ffreestanding /clangd-test/foo.cpp Driver produced command: cc1 -cc1 -triple aarch64-unknown-linux-gnu -fsyntax-only -disable-free -clear-ast-before-backend -main-file-name foo.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=non-leaf -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -enable-tlsdesc -target-cpu generic -target-feature +v8a -target-feature +fp-armv8 -target-feature +neon -target-abi aapcs -debugger-tuning=gdb -fdebug-compilation-dir=/clangd-test -fcoverage-compilation-dir=/clangd-test -resource-dir lib/clang/22 -internal-isystem lib/clang/22/include -internal-isystem /usr/local/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -ferror-limit 19 -fno-signed-char -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -no-round-trip-args -target-feature -fmv -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ /clangd-test/foo.cpp Building first preamble for /clangd-test/foo.cpp version null not idle after addDocument UNREACHABLE executed at ../llvm/clang-tools-extra/clangd/unittests/SyncAPI.cpp:22! #0 0x0000b5122fea72fc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd072fc) #1 0x0000b5122fea4dec llvm::sys::RunSignalHandlers() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd04dec) #2 0x0000b5122fea813c SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0 #3 0x0000f07d0f1ca8f8 (linux-vdso.so.1+0x8f8) #4 0x0000f07d0ece2008 __pthread_kill_implementation ./nptl/./nptl/pthread_kill.c:44:76 #5 0x0000f07d0ec9a83c gsignal ./signal/../sysdeps/posix/raise.c:27:6 #6 0x0000f07d0ec87134 abort ./stdlib/./stdlib/abort.c:81:7 #7 0x0000b5122fe53554 llvm::RTTIRoot::anchor() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xcb3554) #8 0x0000b5122fce9db4 clang::clangd::runCodeComplete(clang::clangd::ClangdServer&, llvm::StringRef, clang::clangd::Position, clang::clangd::CodeCompleteOptions) (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xb49db4) #9 0x0000b5122f81c790 clang::clangd::(anonymous namespace)::CompletionTest_DynamicIndexMultiFile_Test::TestBody() CodeCompleteTests.cpp:0:0 #10 0x0000b5122ff01958 testing::Test::Run() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd61958) #11 0x0000b5122ff02c68 testing::TestInfo::Run() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd62c68) #12 0x0000b5122ff03830 testing::TestSuite::Run() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd63830) #13 0x0000b5122ff14578 testing::internal::UnitTestImpl::RunAllTests() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd74578) #14 0x0000b5122ff13ee4 testing::UnitTest::Run() (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd73ee4) #15 0x0000b5122feedd44 main (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xd4dd44) #16 0x0000f07d0ec87400 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3 #17 0x0000f07d0ec874d8 call_init ./csu/../csu/libc-start.c:128:20 #18 0x0000f07d0ec874d8 __libc_start_main ./csu/../csu/libc-start.c:379:5 #19 0x0000b5122f6352b0 _start (/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0x4952b0) -- exit: -6 -- shard JSON output does not exist: /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests-Clangd Unit Tests-315154-112-335.json ******************** 
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 27, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-darwin running on doug-worker-3 while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/23/builds/15023

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure) ******************** TEST 'Clang :: Format/dry-run-warning.cpp' FAILED ******************** Exit Code: 127 Command Output (stdout): -- # RUN: at line 1 echo '{' > /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/clang/test/Format/Output/dry-run-warning.cpp.tmp.json # executed command: echo '{' # note: command had no output on stdout or stderr # RUN: at line 2 echo ' "married": true' >> /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/clang/test/Format/Output/dry-run-warning.cpp.tmp.json # executed command: echo ' "married": true' # note: command had no output on stdout or stderr # RUN: at line 3 echo '}' >> /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/clang/test/Format/Output/dry-run-warning.cpp.tmp.json # executed command: echo '}' # note: command had no output on stdout or stderr # RUN: at line 5 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/clang-format -n -style=LLVM /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/clang/test/Format/Output/dry-run-warning.cpp.tmp.json 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/clang/test/Format/dry-run-warning.cpp -allow-empty # executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/clang-format -n -style=LLVM /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/clang/test/Format/Output/dry-run-warning.cpp.tmp.json # .---command stderr------------ # | Could not create process (/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/clang-format) due to [Errno 24] Too many open files # `----------------------------- # error: command failed with exit status: 127 -- ******************** 
dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
…165235) We used to do this the other way around to work around an awkwardness with CheckStore, namely that we shouldn't check pointers for being activated when activating them. Add a parameter to CheckStore instead and call CheckStore() _before_ activating and initializing the pointers in the respective opcode implementations. Fixes llvm#164975
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
…165235) We used to do this the other way around to work around an awkwardness with CheckStore, namely that we shouldn't check pointers for being activated when activating them. Add a parameter to CheckStore instead and call CheckStore() _before_ activating and initializing the pointers in the respective opcode implementations. Fixes llvm#164975
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
…165235) We used to do this the other way around to work around an awkwardness with CheckStore, namely that we shouldn't check pointers for being activated when activating them. Add a parameter to CheckStore instead and call CheckStore() _before_ activating and initializing the pointers in the respective opcode implementations. Fixes llvm#164975
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:bytecode Issues for the clang bytecode constexpr interpreter clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

3 participants