[clang] 20d7fff - [clang][Interp] Fix atomic builtins with integral pointers
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 23 04:15:46 PDT 2024
Author: Timm Bäder
Date: 2024-07-23T13:15:32+02:00
New Revision: 20d7fff5eaaa9d78807035d63e5c503bfc1b497e
URL: https://github.com/llvm/llvm-project/commit/20d7fff5eaaa9d78807035d63e5c503bfc1b497e
DIFF: https://github.com/llvm/llvm-project/commit/20d7fff5eaaa9d78807035d63e5c503bfc1b497e.diff
LOG: [clang][Interp] Fix atomic builtins with integral pointers
Check the integral pointer value.
Added:
Modified:
clang/lib/AST/Interp/InterpBuiltin.cpp
clang/test/AST/Interp/atomic.c
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 98928b3c22d7c..c170042144acc 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -942,15 +942,29 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
if (Ptr.isZero())
return returnBool(true);
- QualType PointeeType = Call->getArg(1)
- ->IgnoreImpCasts()
- ->getType()
- ->castAs<PointerType>()
- ->getPointeeType();
- // OK, we will inline operations on this object.
- if (!PointeeType->isIncompleteType() &&
- S.getCtx().getTypeAlignInChars(PointeeType) >= Size)
- return returnBool(true);
+ if (Ptr.isIntegralPointer()) {
+ uint64_t IntVal = Ptr.getIntegerRepresentation();
+ if (APSInt(APInt(64, IntVal, false), true).isAligned(Size.getAsAlign()))
+ return returnBool(true);
+ }
+
+ const Expr *PtrArg = Call->getArg(1);
+ // Otherwise, check if the type's alignment against Size.
+ if (const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
+ // Drop the potential implicit-cast to 'const volatile void*', getting
+ // the underlying type.
+ if (ICE->getCastKind() == CK_BitCast)
+ PtrArg = ICE->getSubExpr();
+ }
+
+ if (auto PtrTy = PtrArg->getType()->getAs<PointerType>()) {
+ QualType PointeeType = PtrTy->getPointeeType();
+ if (!PointeeType->isIncompleteType() &&
+ S.getCtx().getTypeAlignInChars(PointeeType) >= Size) {
+ // OK, we will inline operations on this object.
+ return returnBool(true);
+ }
+ }
}
}
diff --git a/clang/test/AST/Interp/atomic.c b/clang/test/AST/Interp/atomic.c
index c5fd9ab222934..c8469d4a938b8 100644
--- a/clang/test/AST/Interp/atomic.c
+++ b/clang/test/AST/Interp/atomic.c
@@ -58,3 +58,16 @@ _Static_assert(atomic_is_lock_free((atomic_short*)0), "");
_Static_assert(atomic_is_lock_free((atomic_int*)0), "");
_Static_assert(atomic_is_lock_free((atomic_long*)0), "");
_Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), "");
+
+_Static_assert(__atomic_always_lock_free(1, (void*)1), "");
+_Static_assert(__atomic_always_lock_free(1, (void*)-1), "");
+_Static_assert(!__atomic_always_lock_free(4, (void*)2), "");
+_Static_assert(!__atomic_always_lock_free(4, (void*)-2), "");
+_Static_assert(__atomic_always_lock_free(4, (void*)4), "");
+_Static_assert(__atomic_always_lock_free(4, (void*)-4), "");
+
+_Static_assert(__atomic_always_lock_free(1, "string"), "");
+_Static_assert(!__atomic_always_lock_free(2, "string"), "");
+_Static_assert(__atomic_always_lock_free(2, (int[2]){}), "");
+void dummyfn();
+_Static_assert(__atomic_always_lock_free(2, dummyfn) || 1, "");
More information about the cfe-commits
mailing list