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