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;
+}
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;
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to