[PATCH] Fix to PR15537 - assertion failure when comparing atomic unsigned int to int.

Serge Pavlov sepavloff at gmail.com
Thu Apr 18 06:56:19 PDT 2013


  Patch updated

  In fact UsualArithmeticConversions calls UsualUnaryConversions, it eventually makes the
  lvalue-to-rvalue conversion, which converts an atomic type to the corresponding base
  type. However, UsualArithmeticConversions may be called only for arithmetic types but a
  comparison may involve wider range of types. The method isArithmeticType recognizes
  arithmetic types but it doesn't work with atomic types, so the atomic-to-non-atomic
  conversion must be made before, and this is a problem.

  It is possible to call UsualUnaryConversion always at the beginning of
  Sema::CheckCompareOperands. It however means that if arithmetic values are compared
  (apparently the most frequent case), UsualUnaryConversion are executed twice, which
  is not optimal.

  The modified patch doesn't use UsualUnaryConversion but makes only conversion of
  atomic type. It must minimize the overhead of type transformations.

Hi doug.gregor,

http://llvm-reviews.chandlerc.com/D599

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D599?vs=1453&id=1684#toc

Files:
  lib/Sema/SemaExpr.cpp
  test/Sema/atomic-expr.c

Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -7207,6 +7207,20 @@
   QualType LHSType = LHS.get()->getType();
   QualType RHSType = RHS.get()->getType();
 
+  // Unfold atomic types.
+  if (const AtomicType *Atomic = LHSType->getAs<AtomicType>()) {
+    QualType T = Atomic->getValueType().getUnqualifiedType();
+    LHS = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic,
+                                         LHS.get(), 0, VK_RValue));
+    LHSType = LHS.get()->getType();
+  }
+  if (const AtomicType *Atomic = RHSType->getAs<AtomicType>()) {
+    QualType T = Atomic->getValueType().getUnqualifiedType();
+    RHS = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic,
+                                         RHS.get(), 0, VK_RValue));
+    RHSType = RHS.get()->getType();
+  }
+
   Expr *LHSStripped = LHS.get()->IgnoreParenImpCasts();
   Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts();
 
Index: test/Sema/atomic-expr.c
===================================================================
--- test/Sema/atomic-expr.c
+++ test/Sema/atomic-expr.c
@@ -45,3 +45,59 @@
 void func_10 (int* xp) {
   *xp <<= data2;
 }
+
+// Compare operations
+
+enum entype { one, two, three };
+typedef void (*func_type)();
+
+_Atomic(enum entype) atomic_enum = one;
+_Atomic(float) atomic_flt = 1.0;
+int * _Atomic atomic_ptr;
+_Atomic(void *) atomic_void;
+_Atomic(func_type) atomic_func;
+
+// PR15537
+int comp_01 () {
+  return data1 == data2;
+}
+
+int comp_02 (int x) {
+  return data1 < x;
+}
+
+int comp_03 (_Atomic(int) *p) {
+  return *p >= data1;
+}
+
+int comp_04 (int x) {
+  return atomic_enum < x;
+}
+
+int comp_05 (int x) {
+  return atomic_flt >= x;
+}
+
+int comp_06 (_Atomic(double) *p) {
+  return atomic_flt < *p;
+}
+
+int comp_07 (int *p) {
+  return atomic_ptr == p;
+}
+
+int comp_08 (int *p) {
+  return p == atomic_void;
+}
+
+int comp_09 () {
+  return 0 == atomic_void;
+}
+
+int comp_10 (func_type x) {
+  return atomic_func == x;
+}
+
+int comp_11 () {
+  return atomic_func != 0;
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D599.2.patch
Type: text/x-patch
Size: 2144 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130418/03fb6d3f/attachment.bin>


More information about the cfe-commits mailing list