From 9ac2b8965264a7f20a3e07c913b25c375a080c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 14 Jul 2024 21:24:21 +0200 Subject: [PATCH] [clang][Interp] Diagnose volatile reads --- clang/lib/AST/Interp/Interp.cpp | 23 +++++++++++++++++++++++ clang/test/AST/Interp/literals.cpp | 6 ++++++ 2 files changed, 29 insertions(+) diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 70a470021e7f22..7b2c0480f80ae5 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -444,6 +444,27 @@ bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return false; } +bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK) { + assert(Ptr.isLive()); + + // FIXME: This check here might be kinda expensive. Maybe it would be better + // to have another field in InlineDescriptor for this? + if (!Ptr.isBlockPointer()) + return true; + + QualType PtrType = Ptr.getType(); + if (!PtrType.isVolatileQualified()) + return true; + + const SourceInfo &Loc = S.Current->getSource(OpPC); + if (S.getLangOpts().CPlusPlus) + S.FFDiag(Loc, diag::note_constexpr_access_volatile_type) << AK << PtrType; + else + S.FFDiag(Loc); + return false; +} + bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { assert(Ptr.isLive()); @@ -508,6 +529,8 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return false; if (!CheckMutable(S, OpPC, Ptr)) return false; + if (!CheckVolatile(S, OpPC, Ptr, AK)) + return false; return true; } diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index af5bcb6d48ae7e..6c214f5a6efa73 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1290,3 +1290,9 @@ namespace UnaryOpError { } } #endif + +namespace VolatileReads { + const volatile int b = 1; + static_assert(b, ""); // both-error {{not an integral constant expression}} \ + // both-note {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}} +}