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

Reply via email to