r335925 - PR37979: integral promotions in C++ treat enum bit-fields like enums,

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 29 13:46:26 PDT 2018


Should be fixed in r336013. Thanks for pointing this out.

On Fri, 29 Jun 2018 at 11:24, Galina Kistanova via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Hello Richard,
>
> This commit broke tests at one of our builders:
>
> http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/10599
>
> Failing Tests (1):
>     Clang :: CXX/conv/conv.prom/p5.cpp
>
> Please have a look?
>
> Thanks
>
> Galina
>
> On Thu, Jun 28, 2018 at 2:17 PM, Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: rsmith
>> Date: Thu Jun 28 14:17:55 2018
>> New Revision: 335925
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=335925&view=rev
>> Log:
>> PR37979: integral promotions in C++ treat enum bit-fields like enums,
>> not like bit-fields.
>>
>> We used to get this right "by accident", because conversions for the
>> selected built-in overloaded operator would convert the enum bit-field
>> to its corresponding underlying type early. But after DR1687 that no
>> longer happens.
>>
>> Technically this change should also apply to C, where bit-fields only
>> have special promotion rules if the bit-field's declared type is
>> _Bool, int, signed int, or unsigned int, but for GCC compatibility we
>> only look at the bit-width and not the underlying type when performing
>> bit-field integral promotions in C.
>>
>> Added:
>>     cfe/trunk/test/CXX/conv/conv.prom/p5.cpp
>> Modified:
>>     cfe/trunk/lib/AST/ASTContext.cpp
>>     cfe/trunk/lib/Sema/SemaOverload.cpp
>>
>> Modified: cfe/trunk/lib/AST/ASTContext.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=335925&r1=335924&r2=335925&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jun 28 14:17:55 2018
>> @@ -5456,6 +5456,12 @@ QualType ASTContext::isPromotableBitFiel
>>    if (E->isTypeDependent() || E->isValueDependent())
>>      return {};
>>
>> +  // C++ [conv.prom]p5:
>> +  //    If the bit-field has an enumerated type, it is treated as any
>> other
>> +  //    value of that type for promotion purposes.
>> +  if (getLangOpts().CPlusPlus && E->getType()->isEnumeralType())
>> +    return {};
>> +
>>    // FIXME: We should not do this unless E->refersToBitField() is true.
>> This
>>    // matters in C where getSourceBitField() will find bit-fields for
>> various
>>    // cases where the source expression is not a bit-field designator.
>> @@ -5482,13 +5488,15 @@ QualType ASTContext::isPromotableBitFiel
>>    //
>>    // FIXME: C does not permit promotion of a 'long : 3' bitfield to int.
>>    //        We perform that promotion here to match GCC and C++.
>> +  // FIXME: C does not permit promotion of an enum bit-field whose rank
>> is
>> +  //        greater than that of 'int'. We perform that promotion to
>> match GCC.
>>    if (BitWidth < IntSize)
>>      return IntTy;
>>
>>    if (BitWidth == IntSize)
>>      return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;
>>
>> -  // Types bigger than int are not subject to promotions, and therefore
>> act
>> +  // Bit-fields wider than int are not subject to promotions, and
>> therefore act
>>    // like the base type. GCC has some weird bugs in this area that we
>>    // deliberately do not follow (GCC follows a pre-standard resolution to
>>    // C's DR315 which treats bit-width as being part of the type, and
>> this leaks
>>
>> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=335925&r1=335924&r2=335925&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Jun 28 14:17:55 2018
>> @@ -2007,6 +2007,14 @@ bool Sema::IsIntegralPromotion(Expr *Fro
>>          isCompleteType(From->getLocStart(), FromType))
>>        return Context.hasSameUnqualifiedType(
>>            ToType, FromEnumType->getDecl()->getPromotionType());
>> +
>> +    // C++ [conv.prom]p5:
>> +    //   If the bit-field has an enumerated type, it is treated as any
>> other
>> +    //   value of that type for promotion purposes.
>> +    //
>> +    // ... so do not fall through into the bit-field checks below in C++.
>> +    if (getLangOpts().CPlusPlus)
>> +      return false;
>>    }
>>
>>    // C++0x [conv.prom]p2:
>> @@ -2054,6 +2062,11 @@ bool Sema::IsIntegralPromotion(Expr *Fro
>>    // other value of that type for promotion purposes (C++ 4.5p3).
>>    // FIXME: We should delay checking of bit-fields until we actually
>> perform the
>>    // conversion.
>> +  //
>> +  // FIXME: In C, only bit-fields of types _Bool, int, or unsigned int
>> may be
>> +  // promoted, per C11 6.3.1.1/2. We promote all bit-fields (including
>> enum
>> +  // bit-fields and those whose underlying type is larger than int) for
>> GCC
>> +  // compatibility.
>>    if (From) {
>>      if (FieldDecl *MemberDecl = From->getSourceBitField()) {
>>        llvm::APSInt BitWidth;
>>
>> Added: cfe/trunk/test/CXX/conv/conv.prom/p5.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/conv/conv.prom/p5.cpp?rev=335925&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/CXX/conv/conv.prom/p5.cpp (added)
>> +++ cfe/trunk/test/CXX/conv/conv.prom/p5.cpp Thu Jun 28 14:17:55 2018
>> @@ -0,0 +1,19 @@
>> +// RUN: %clang_cc1 -verify %s
>> +// expected-no-diagnostics
>> +
>> +// A prvalue for an integral bit-field can be converted to a prvalue of
>> type
>> +// int if int can represent all the values of the bit-field
>> +struct X { long long e : 1; };
>> +static_assert(sizeof(+X().e) == sizeof(int), "");
>> +static_assert(sizeof(X().e + 1) == sizeof(int), "");
>> +static_assert(sizeof(true ? X().e : 0) == sizeof(int), "");
>> +
>> +enum E { a = __LONG_LONG_MAX__ };
>> +static_assert(sizeof(E{}) == sizeof(long long), "");
>> +
>> +// If the bit-field has an enumerated type, it is treated as any other
>> value of
>> +// that [enumerated] type for promotion purposes.
>> +struct Y { E e : 1; };
>> +static_assert(sizeof(+Y().e) == sizeof(long long), "");
>> +static_assert(sizeof(Y().e + 1) == sizeof(long long), "");
>> +static_assert(sizeof(true ? Y().e : 0) == sizeof(long long), "");
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180629/8985d5ee/attachment.html>


More information about the cfe-commits mailing list