Skip to content

Commit b0bcc8e

Browse files
tbaederryuxuanchen1997
authored andcommitted
[clang][Interp] Fix atomic builtins with integral pointers
Summary: Check the integral pointer value. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251311
1 parent 2c75f2b commit b0bcc8e

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

clang/lib/AST/Interp/InterpBuiltin.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -942,15 +942,29 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
942942
if (Ptr.isZero())
943943
return returnBool(true);
944944

945-
QualType PointeeType = Call->getArg(1)
946-
->IgnoreImpCasts()
947-
->getType()
948-
->castAs<PointerType>()
949-
->getPointeeType();
950-
// OK, we will inline operations on this object.
951-
if (!PointeeType->isIncompleteType() &&
952-
S.getCtx().getTypeAlignInChars(PointeeType) >= Size)
953-
return returnBool(true);
945+
if (Ptr.isIntegralPointer()) {
946+
uint64_t IntVal = Ptr.getIntegerRepresentation();
947+
if (APSInt(APInt(64, IntVal, false), true).isAligned(Size.getAsAlign()))
948+
return returnBool(true);
949+
}
950+
951+
const Expr *PtrArg = Call->getArg(1);
952+
// Otherwise, check if the type's alignment against Size.
953+
if (const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
954+
// Drop the potential implicit-cast to 'const volatile void*', getting
955+
// the underlying type.
956+
if (ICE->getCastKind() == CK_BitCast)
957+
PtrArg = ICE->getSubExpr();
958+
}
959+
960+
if (auto PtrTy = PtrArg->getType()->getAs<PointerType>()) {
961+
QualType PointeeType = PtrTy->getPointeeType();
962+
if (!PointeeType->isIncompleteType() &&
963+
S.getCtx().getTypeAlignInChars(PointeeType) >= Size) {
964+
// OK, we will inline operations on this object.
965+
return returnBool(true);
966+
}
967+
}
954968
}
955969
}
956970

clang/test/AST/Interp/atomic.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,16 @@ _Static_assert(atomic_is_lock_free((atomic_short*)0), "");
5858
_Static_assert(atomic_is_lock_free((atomic_int*)0), "");
5959
_Static_assert(atomic_is_lock_free((atomic_long*)0), "");
6060
_Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), "");
61+
62+
_Static_assert(__atomic_always_lock_free(1, (void*)1), "");
63+
_Static_assert(__atomic_always_lock_free(1, (void*)-1), "");
64+
_Static_assert(!__atomic_always_lock_free(4, (void*)2), "");
65+
_Static_assert(!__atomic_always_lock_free(4, (void*)-2), "");
66+
_Static_assert(__atomic_always_lock_free(4, (void*)4), "");
67+
_Static_assert(__atomic_always_lock_free(4, (void*)-4), "");
68+
69+
_Static_assert(__atomic_always_lock_free(1, "string"), "");
70+
_Static_assert(!__atomic_always_lock_free(2, "string"), "");
71+
_Static_assert(__atomic_always_lock_free(2, (int[2]){}), "");
72+
void dummyfn();
73+
_Static_assert(__atomic_always_lock_free(2, dummyfn) || 1, "");

0 commit comments

Comments
 (0)