llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> ... if we're in the bottom frame. --- Full diff: https://github.com/llvm/llvm-project/pull/208990.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Interp.cpp (+11-1) - (modified) clang/test/AST/ByteCode/literals.cpp (+16-4) ``````````diff diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 0adcdfe6e78c9..169aab5ed9f3d 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -857,11 +857,12 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B) { bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) { assert(!B->isExtern()); const auto &Desc = *reinterpret_cast<const InlineDescriptor *>(B->rawData()); + const Descriptor *BlockDesc = B->getDescriptor(); if (!CheckLifetime(S, OpPC, Desc.LifeState, B, AK_Read)) return false; if (!Desc.IsInitialized) return DiagnoseUninitialized(S, OpPC, /*Extern=*/false, B, AK_Read); - if (B->getDescriptor()->IsVolatile) { + if (BlockDesc->IsVolatile) { if (!S.getLangOpts().CPlusPlus) return Invalid(S, OpPC); @@ -872,6 +873,15 @@ bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) { S.Note(D->getLocation(), diag::note_constexpr_volatile_here) << 1; return false; } + + // A non-const local variable while we don't have a parent frame. This must be + // a local variable in a statement expression. + if (S.Current->isBottomFrame() && !BlockDesc->IsConst && + !BlockDesc->IsTemporary && !S.checkingPotentialConstantExpression()) { + if (const ValueDecl *VD = BlockDesc->asValueDecl()) + diagnoseNonConstVariable(S, OpPC, VD); + return false; + } return true; } diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp index eafab2e1ab64d..3b24b166e39a7 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -1326,17 +1326,29 @@ namespace StmtExprs { constexpr long a(bool x) { return x ? 0 : (intptr_t)&&lbl + (0 && ({lbl: 0;})); } } - /// GCC agrees with the bytecode interpreter here. + /// FIXME: This should be accepted. + /// BUT accepting this breaks test/OpenMP/for_codegen.cpp void switchInSE() { - static_assert(({ // ref-error {{not an integral constant expression}} - int i = 20; + static_assert(({ // both-error {{not an integral constant expression}} + int i = 20; // expected-note {{declared here}} switch(10) { - case 10: i = 300; // ref-note {{a constant expression cannot modify an object that is visible outside that expression}} + case 10: i = 300; // ref-note {{a constant expression cannot modify an object that is visible outside that expression}} \ + // expected-note {{read of non-const variable 'i'}} } i; }) == 300); } + /// We reject the test above because of the read from i, not because of the modification. + /// FIXME: The sourcelocation for the broken read is incorrect. + void switchInSE2() { + static_assert(({ // both-error {{not an integral constant expression}} + int i = 20; // expected-note {{read of non-const variable}} \ + // both-note {{declared here}} + i; // ref-note {{read of non-const variable}} + }) == 300); + } + constexpr int f(int k) { switch (k) { case 0: `````````` </details> https://github.com/llvm/llvm-project/pull/208990 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
