Author: Timm Bäder Date: 2024-05-24T16:40:38+02:00 New Revision: d8c8c8c7b91ce51f3e2fc088a5fd365b23cd9889
URL: https://github.com/llvm/llvm-project/commit/d8c8c8c7b91ce51f3e2fc088a5fd365b23cd9889 DIFF: https://github.com/llvm/llvm-project/commit/d8c8c8c7b91ce51f3e2fc088a5fd365b23cd9889.diff LOG: [clang][Interp] Diagnose dummy assignments differently Incremental change here, but a step in the right direction. Before, an assignment to a dummy variable was diagnosed as a "read of a non-const variable". Added: Modified: clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpBuiltin.cpp clang/test/AST/Interp/cxx03.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index de5390596d632..145fa65791da2 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -457,7 +457,7 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckConstant(S, OpPC, Ptr)) return false; - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Read)) return false; if (!CheckExtern(S, OpPC, Ptr)) return false; @@ -477,7 +477,7 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckLive(S, OpPC, Ptr, AK_Assign)) return false; - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Assign)) return false; if (!CheckExtern(S, OpPC, Ptr)) return false; @@ -660,7 +660,8 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) { return diagnoseUnknownDecl(S, OpPC, D); } -bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { +bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK) { if (!Ptr.isDummy()) return true; @@ -669,7 +670,15 @@ bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!D) return false; - return diagnoseUnknownDecl(S, OpPC, D); + if (AK == AK_Read || AK == AK_Increment || AK == AK_Decrement) + return diagnoseUnknownDecl(S, OpPC, D); + + assert(AK == AK_Assign); + if (S.getLangOpts().CPlusPlus11) { + const SourceInfo &E = S.Current->getSource(OpPC); + S.FFDiag(E, diag::note_constexpr_modify_global); + } + return false; } bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F, diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index bcb6fb4d65218..eca1792e64718 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -56,7 +56,8 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK); /// Checks if a pointer is a dummy pointer. -bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr); +bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK); /// Checks if a pointer is null. bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr, @@ -588,7 +589,7 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { template <PrimType Name, class T = typename PrimConv<Name>::T> bool Inc(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop<Pointer>(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Increment)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) return false; @@ -602,7 +603,7 @@ bool Inc(InterpState &S, CodePtr OpPC) { template <PrimType Name, class T = typename PrimConv<Name>::T> bool IncPop(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop<Pointer>(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Increment)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) return false; @@ -617,7 +618,7 @@ bool IncPop(InterpState &S, CodePtr OpPC) { template <PrimType Name, class T = typename PrimConv<Name>::T> bool Dec(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop<Pointer>(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Decrement)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) return false; @@ -631,7 +632,7 @@ bool Dec(InterpState &S, CodePtr OpPC) { template <PrimType Name, class T = typename PrimConv<Name>::T> bool DecPop(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop<Pointer>(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Decrement)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) return false; diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 565c85bc2e0c2..00206d09c113d 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -214,7 +214,7 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, if (!CheckLive(S, OpPC, StrPtr, AK_Read)) return false; - if (!CheckDummy(S, OpPC, StrPtr)) + if (!CheckDummy(S, OpPC, StrPtr, AK_Read)) return false; assert(StrPtr.getFieldDesc()->isPrimitiveArray()); diff --git a/clang/test/AST/Interp/cxx03.cpp b/clang/test/AST/Interp/cxx03.cpp index b6aaf0840cfb3..70ae4134842b5 100644 --- a/clang/test/AST/Interp/cxx03.cpp +++ b/clang/test/AST/Interp/cxx03.cpp @@ -24,3 +24,8 @@ namespace NonLValueMemberExpr { const int &TT1::subobj_init = PODType().value; } + +void LambdaAccessingADummy() { + int d; + int a9[1] = {[d = 0] = 1}; // both-error {{is not an integral constant expression}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits