[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