Skip to content

[Clang] Fix crash with implicit int-to-pointer conversion #114218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

ostannard
Copy link
Collaborator

If an integer is passed to the pointer argument of the __atomic_test_and_set or __atomic_clear builtins with the int-conversion error disabled or downgraded, we crashed in codegen due to assuming that the type is always a pointer after skip[ping past implicit casts.

Fixes #111293.

If an integer is passed to the pointer argument of the
__atomic_test_and_set or __atomic_clear builtins with the int-conversion
error disabled or downgraded, we crashed in codegen due to assuming that
the type is always a pointer after skip[ping past implicit casts.

Fixes llvm#111293.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Oct 30, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2024

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Oliver Stannard (ostannard)

Changes

If an integer is passed to the pointer argument of the __atomic_test_and_set or __atomic_clear builtins with the int-conversion error disabled or downgraded, we crashed in codegen due to assuming that the type is always a pointer after skip[ping past implicit casts.

Fixes #111293.


Full diff: https://github.com/llvm/llvm-project/pull/114218.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-2)
  • (modified) clang/test/CodeGen/atomic-ops.c (+7-3)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 65d7f5c54a1913..87955a2c158454 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4928,8 +4928,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
     // Look at the argument type to determine whether this is a volatile
     // operation. The parameter type is always volatile.
     QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
+    QualType PointeeTy = PtrTy->getPointeeType();
     bool Volatile =
-        PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
+        PointeeTy.isNull() ? false : PointeeTy.isVolatileQualified();
 
     Address Ptr =
         EmitPointerWithAlignment(E->getArg(0)).withElementType(Int8Ty);
@@ -5011,8 +5012,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
 
   case Builtin::BI__atomic_clear: {
     QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
+    QualType PointeeTy = PtrTy->getPointeeType();
     bool Volatile =
-        PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
+        PointeeTy.isNull() ? false : PointeeTy.isVolatileQualified();
 
     Address Ptr = EmitPointerWithAlignment(E->getArg(0));
     Ptr = Ptr.withElementType(Int8Ty);
diff --git a/clang/test/CodeGen/atomic-ops.c b/clang/test/CodeGen/atomic-ops.c
index b6060dcc540f90..4c7d674836cd36 100644
--- a/clang/test/CodeGen/atomic-ops.c
+++ b/clang/test/CodeGen/atomic-ops.c
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 -Wno-error=int-conversion | FileCheck %s
 // REQUIRES: x86-registered-target
 
 // Also test serialization of atomic operations here, to avoid duplicating the
 // test.
-// RUN: %clang_cc1 %s -emit-pch -o %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9
-// RUN: %clang_cc1 %s -include-pch %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-pch -o %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 -Wno-error=int-conversion
+// RUN: %clang_cc1 %s -include-pch %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 -Wno-error=int-conversion -emit-llvm -o - | FileCheck %s
 #ifndef ALREADY_INCLUDED
 #define ALREADY_INCLUDED
 
@@ -310,10 +310,14 @@ void test_and_set(void) {
   __atomic_test_and_set(&flag1, memory_order_seq_cst);
   // CHECK: atomicrmw volatile xchg ptr @flag2, i8 1 acquire, align 1
   __atomic_test_and_set(&flag2, memory_order_acquire);
+  // CHECK: atomicrmw xchg ptr inttoptr (i32 32768 to ptr), i8 1 acquire, align 1
+  __atomic_test_and_set(0x8000, memory_order_acquire);
   // CHECK: store atomic volatile i8 0, ptr @flag2 release, align 1
   __atomic_clear(&flag2, memory_order_release);
   // CHECK: store atomic i8 0, ptr @flag1 seq_cst, align 1
   __atomic_clear(&flag1, memory_order_seq_cst);
+  // CHECK: store atomic i8 0, ptr inttoptr (i32 32768 to ptr) seq_cst, align 1
+  __atomic_clear(0x8000, memory_order_seq_cst);
 }
 
 struct Sixteen {

@efriedma-quic
Copy link
Collaborator

Is there some discussion somewhere of why the change from hasErrorOccurred to hasUnrecoverableErrorOccurred happened?

@@ -4928,8 +4928,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// Look at the argument type to determine whether this is a volatile
// operation. The parameter type is always volatile.
QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IgnoreImpCasts is usually wrong; in general, it's going to find an unrelated type.

If __atomic_test_and_set is overloaded to have both a volatile and non-volatile variant, it should be using custom type-checking in Sema.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related testcase: void f() { volatile int x[10]; __atomic_test_and_set(x,0); }.

@shafik
Copy link
Collaborator

shafik commented Oct 30, 2024

Is there some discussion somewhere of why the change from hasErrorOccurred to hasUnrecoverableErrorOccurred happened?

I had asked about this in the original PR here: #84146 but did not get a response.

@ostannard
Copy link
Collaborator Author

If __atomic_test_and_set is overloaded to have both a volatile and non-volatile variant, it should be using custom type-checking in Sema.

Looking at the code again, there's a separate system used to codegen most of the atomic builtins, so I've switched to using that. That completely replaces this change, so I've started a new PR #120449, and will close this one.

I had asked about this in the original PR here: #84146 but did not get a response.

I've added a comment there.

@ostannard ostannard closed this Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Clang] Assertion failed on __atomic_test_and_set
4 participants