[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 13:48:58 PDT 2012


On Apr 12, 2012, at 11:09 AM, Jordy Rose <jediknil at belkadan.com> wrote:

> Nitpicking: how about tryAtomicConversion instead of isAtomicConversion, since it's not a pure function?

Sure, r154613.

	- Doug

> 
> On Thu, 12 Apr 2012 17:51:56 -0000, Douglas Gregor wrote:
>> 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);
>> +}
>> 
>> 
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 




More information about the cfe-commits mailing list