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, ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits