leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, rsmith.
leonardchan added a project: clang.

Compiling the following causes clang to crash

  void cmp(char *x,  __attribute__((address_space(2))) char *y) {
     0 ? x : y;
  }

with the message: "wrong cast for pointers in different address spaces(must be 
an address space cast)!"

This is because during IR emission, the source and dest type for a bitcast 
should not have differing address spaces.

This fix ensures that an AddressSpaceConversion is used instead while retaining 
the `pointer type mismatch` warnings.


Repository:
  rC Clang

https://reviews.llvm.org/D50278

Files:
  lib/Sema/SemaExpr.cpp
  test/Sema/address_spaces_cond_op.c
  test/Sema/address_spaces_cond_op_ir.c


Index: test/Sema/address_spaces_cond_op_ir.c
===================================================================
--- /dev/null
+++ test/Sema/address_spaces_cond_op_ir.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | FileCheck %s
+
+#define _AS1 __attribute__((address_space(1)))
+#define _AS2 __attribute__((address_space(2)))
+
+char *cmp(_AS1 char *x, _AS2 char *y) {
+  return x < y ? x : y;
+}
+
+// CHECK:       %x.addr = alloca i8 addrspace(1)*, align 8
+// CHECK-NEXT:  %y.addr = alloca i8 addrspace(2)*, align 8
+// CHECK-NEXT:  store i8 addrspace(1)* %x, i8 addrspace(1)** %x.addr, align 8
+// CHECK-NEXT:  store i8 addrspace(2)* %y, i8 addrspace(2)** %y.addr, align 8
+// CHECK-NEXT:  %0 = load i8 addrspace(1)*, i8 addrspace(1)** %x.addr, align 8
+// CHECK-NEXT:  %1 = load i8 addrspace(2)*, i8 addrspace(2)** %y.addr, align 8
+// CHECK-NEXT:  %2 = addrspacecast i8 addrspace(2)* %1 to i8 addrspace(1)*
Index: test/Sema/address_spaces_cond_op.c
===================================================================
--- /dev/null
+++ test/Sema/address_spaces_cond_op.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+#define _AS1 __attribute__((address_space(1)))
+#define _AS2 __attribute__((address_space(2)))
+
+char *cmp(_AS1 char *x, _AS2 char *y) {
+  return x < y ? x : y;
+}
+
+// CHECK:      |-ImplicitCastExpr {{.*}} 'void *' <AddressSpaceConversion>
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__attribute__((address_space(1))) 
char *' <LValueToRValue>
+// CHECK-NEXT: |   `-DeclRefExpr {{.*}} '__attribute__((address_space(1))) 
char *' {{.*}} 'x' '__attribute__((address_space(1))) char *'
+
+// CHECK:     `-ImplicitCastExpr {{.*}} 'void *' <AddressSpaceConversion>
+// CHECK-NEXT:  `-ImplicitCastExpr {{.*}} '__attribute__((address_space(2))) 
char *' <LValueToRValue>
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} '__attribute__((address_space(2))) char 
*' {{.*}} 'y' '__attribute__((address_space(2))) char *'
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -6492,13 +6492,11 @@
   // Thus for conditional operator we merge CVR and address space unqualified
   // pointees and if there is a composite type we return a pointer to it with
   // merged qualifiers.
+  LHSCastKind =
+      LAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
+  RHSCastKind =
+      RAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
   if (S.getLangOpts().OpenCL) {
-    LHSCastKind = LAddrSpace == ResultAddrSpace
-                      ? CK_BitCast
-                      : CK_AddressSpaceConversion;
-    RHSCastKind = RAddrSpace == ResultAddrSpace
-                      ? CK_BitCast
-                      : CK_AddressSpaceConversion;
     lhQual.removeAddressSpace();
     rhQual.removeAddressSpace();
   }


Index: test/Sema/address_spaces_cond_op_ir.c
===================================================================
--- /dev/null
+++ test/Sema/address_spaces_cond_op_ir.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | FileCheck %s
+
+#define _AS1 __attribute__((address_space(1)))
+#define _AS2 __attribute__((address_space(2)))
+
+char *cmp(_AS1 char *x, _AS2 char *y) {
+  return x < y ? x : y;
+}
+
+// CHECK:       %x.addr = alloca i8 addrspace(1)*, align 8
+// CHECK-NEXT:  %y.addr = alloca i8 addrspace(2)*, align 8
+// CHECK-NEXT:  store i8 addrspace(1)* %x, i8 addrspace(1)** %x.addr, align 8
+// CHECK-NEXT:  store i8 addrspace(2)* %y, i8 addrspace(2)** %y.addr, align 8
+// CHECK-NEXT:  %0 = load i8 addrspace(1)*, i8 addrspace(1)** %x.addr, align 8
+// CHECK-NEXT:  %1 = load i8 addrspace(2)*, i8 addrspace(2)** %y.addr, align 8
+// CHECK-NEXT:  %2 = addrspacecast i8 addrspace(2)* %1 to i8 addrspace(1)*
Index: test/Sema/address_spaces_cond_op.c
===================================================================
--- /dev/null
+++ test/Sema/address_spaces_cond_op.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+#define _AS1 __attribute__((address_space(1)))
+#define _AS2 __attribute__((address_space(2)))
+
+char *cmp(_AS1 char *x, _AS2 char *y) {
+  return x < y ? x : y;
+}
+
+// CHECK:      |-ImplicitCastExpr {{.*}} 'void *' <AddressSpaceConversion>
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__attribute__((address_space(1))) char *' <LValueToRValue>
+// CHECK-NEXT: |   `-DeclRefExpr {{.*}} '__attribute__((address_space(1))) char *' {{.*}} 'x' '__attribute__((address_space(1))) char *'
+
+// CHECK:     `-ImplicitCastExpr {{.*}} 'void *' <AddressSpaceConversion>
+// CHECK-NEXT:  `-ImplicitCastExpr {{.*}} '__attribute__((address_space(2))) char *' <LValueToRValue>
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} '__attribute__((address_space(2))) char *' {{.*}} 'y' '__attribute__((address_space(2))) char *'
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -6492,13 +6492,11 @@
   // Thus for conditional operator we merge CVR and address space unqualified
   // pointees and if there is a composite type we return a pointer to it with
   // merged qualifiers.
+  LHSCastKind =
+      LAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
+  RHSCastKind =
+      RAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
   if (S.getLangOpts().OpenCL) {
-    LHSCastKind = LAddrSpace == ResultAddrSpace
-                      ? CK_BitCast
-                      : CK_AddressSpaceConversion;
-    RHSCastKind = RAddrSpace == ResultAddrSpace
-                      ? CK_BitCast
-                      : CK_AddressSpaceConversion;
     lhQual.removeAddressSpace();
     rhQual.removeAddressSpace();
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to