[cfe-commits] r154596 - in /cfe/trunk: lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/atomic-type.cxx

Douglas Gregor dgregor at apple.com
Thu Apr 12 10:51:56 PDT 2012


Author: dgregor
Date: Thu Apr 12 12:51:55 2012
New Revision: 154596

URL: http://llvm.org/viewvc/llvm-project?rev=154596&view=rev
Log:
Compute standard conversion sequences for conversions to atomic
types. The second and third conversions in the sequence are based on
the conversion for the underlying type, so that we get sensible
overloading behavior for, e.g., _Atomic(int) vs. _Atomic(float).

As part of this, actually implement the lvalue-to-rvalue conversion
for atomic types. There is probably a pile of code in SemaExpr that
can now be deleted, but I haven't tracked it down yet.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/atomic-type.cxx

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=154596&r1=154595&r2=154596&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Apr 12 12:51:55 2012
@@ -374,10 +374,6 @@
   QualType T = E->getType();
   assert(!T.isNull() && "r-value conversion on typeless expression?");
 
-  // We can't do lvalue-to-rvalue on atomics yet.
-  if (T->isAtomicType())
-    return Owned(E);
-
   // We don't want to throw lvalue-to-rvalue casts on top of
   // expressions of certain types in C++.
   if (getLangOpts().CPlusPlus &&
@@ -413,6 +409,15 @@
   ExprResult Res = Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue,
                                                   E, 0, VK_RValue));
 
+  // C11 6.3.2.1p2:
+  //   ... if the lvalue has atomic type, the value has the non-atomic version 
+  //   of the type of the lvalue ...
+  if (const AtomicType *Atomic = T->getAs<AtomicType>()) {
+    T = Atomic->getValueType().getUnqualifiedType();
+    Res = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic,
+                                         Res.get(), 0, VK_RValue));
+  }
+  
   return Res;
 }
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=154596&r1=154595&r2=154596&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Apr 12 12:51:55 2012
@@ -1294,6 +1294,11 @@
   return false;
 }
 
+static bool isAtomicConversion(Sema &S, Expr *From, QualType ToType,
+                               bool InOverloadResolution,
+                               StandardConversionSequence &SCS,
+                               bool CStyle);
+  
 /// IsStandardConversion - Determines whether there is a standard
 /// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the
 /// expression From to the type ToType. Standard conversion sequences
@@ -1389,6 +1394,12 @@
       S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
     SCS.First = ICK_Lvalue_To_Rvalue;
 
+    // C11 6.3.2.1p2:
+    //   ... if the lvalue has atomic type, the value has the non-atomic version 
+    //   of the type of the lvalue ...
+    if (const AtomicType *Atomic = FromType->getAs<AtomicType>())
+      FromType = Atomic->getValueType();
+
     // If T is a non-class type, the type of the rvalue is the
     // cv-unqualified version of T. Otherwise, the type of the rvalue
     // is T (C++ 4.1p1). C++ can't get here with class types; in C, we
@@ -1520,13 +1531,11 @@
                                              SCS, CStyle)) {
     SCS.Second = ICK_TransparentUnionConversion;
     FromType = ToType;
-  }  else if (const AtomicType *ToAtomicType = ToType->getAs<AtomicType>()) {
-    // Allow conversion to _Atomic types.  These are C11 and are provided as an
-    // extension in C++ mode.  
-    if (S.Context.hasSameUnqualifiedType(ToAtomicType->getValueType(),
-                                         FromType))
-    SCS.Second = ICK_Identity;
-    FromType = ToType;
+  } else if (isAtomicConversion(S, From, ToType, InOverloadResolution, SCS,
+                                CStyle)) {
+    // isAtomicConversion has updated the standard conversion sequence 
+    // appropriately.
+    return true;
   } else {
     // No second conversion required.
     SCS.Second = ICK_Identity;
@@ -2765,6 +2774,34 @@
   return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
 }
 
+/// \brief - Determine whether this is a conversion from a scalar type to an
+/// atomic type.
+///
+/// If successful, updates \c SCS's second and third steps in the conversion
+/// sequence to finish the conversion.
+static bool isAtomicConversion(Sema &S, Expr *From, QualType ToType,
+                               bool InOverloadResolution,
+                               StandardConversionSequence &SCS,
+                               bool CStyle) {
+  const AtomicType *ToAtomic = ToType->getAs<AtomicType>();
+  if (!ToAtomic)
+    return false;
+  
+  StandardConversionSequence InnerSCS;
+  if (!IsStandardConversion(S, From, ToAtomic->getValueType(), 
+                            InOverloadResolution, InnerSCS,
+                            CStyle, /*AllowObjCWritebackConversion=*/false))
+    return false;
+  
+  SCS.Second = InnerSCS.Second;
+  SCS.setToType(1, InnerSCS.getToType(1));
+  SCS.Third = InnerSCS.Third;
+  SCS.QualificationIncludesObjCLifetime
+    = InnerSCS.QualificationIncludesObjCLifetime;
+  SCS.setToType(2, InnerSCS.getToType(2));
+  return true;
+}
+
 static bool isFirstArgumentCompatibleWithType(ASTContext &Context,
                                               CXXConstructorDecl *Constructor,
                                               QualType Type) {

Modified: cfe/trunk/test/SemaCXX/atomic-type.cxx
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/atomic-type.cxx?rev=154596&r1=154595&r2=154596&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/atomic-type.cxx (original)
+++ cfe/trunk/test/SemaCXX/atomic-type.cxx Thu Apr 12 12:51:55 2012
@@ -10,3 +10,26 @@
 };
 
 user<int> u;
+
+// Test overloading behavior of atomics.
+struct A { };
+
+int &ovl1(_Atomic(int));
+long &ovl1(_Atomic(long));
+float &ovl1(_Atomic(float));
+double &ovl1(_Atomic(A const *const *));
+short &ovl1(_Atomic(A **));
+
+void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
+                      long l, _Atomic(long) al, A const *const *acc,
+                      A const ** ac, A **a) {
+  int& ir1 = ovl1(i);
+  int& ir2 = ovl1(ai);
+  long& lr1 = ovl1(l);
+  long& lr2 = ovl1(al);
+  float &fr1 = ovl1(f);
+  float &fr2 = ovl1(af);
+  double &dr1 = ovl1(acc);
+  double &dr2 = ovl1(ac);
+  short &sr1 = ovl1(a);
+}





More information about the cfe-commits mailing list