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

Jordy Rose jediknil at belkadan.com
Thu Apr 12 11:09:05 PDT 2012


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


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