r183883 - Implement core issue 903: only integer literals with value 0 and prvalues of

Richard Smith richard at metafoo.co.uk
Mon Jun 17 11:04:38 PDT 2013


On Mon, Jun 17, 2013 at 9:38 AM, Jordan Rose <jordan_rose at apple.com> wrote:
> *sigh* I can't say this is the wrong thing to do—in fact, it's the kind of restriction I usually like—but for the record this breaks OS X's (ancient) libstdc++ implementation of <tr1/unordered_map> when compiling under -std=c++11. I don't think that's such an important configuration, though.

That's unfortunate. I assume this is the <tr1/unordered_map> from
g++-4.2? What exotic mechanism is it using to write a null pointer
constant?

> *goes off to unstick internal buildbot*
> Jordan
>
>
> On Jun 12, 2013, at 19:46 , Richard Smith <richard-llvm at metafoo.co.uk> wrote:
>
>> Author: rsmith
>> Date: Wed Jun 12 21:46:14 2013
>> New Revision: 183883
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=183883&view=rev
>> Log:
>> Implement core issue 903: only integer literals with value 0 and prvalues of
>> type std::nullptr_t are null pointer constants from C++11 onwards.
>>
>> Modified:
>>    cfe/trunk/lib/AST/Expr.cpp
>>    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>>    cfe/trunk/test/SemaCXX/lambda-expressions.cpp
>>
>> Modified: cfe/trunk/lib/AST/Expr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183883&r1=183882&r2=183883&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/AST/Expr.cpp (original)
>> +++ cfe/trunk/lib/AST/Expr.cpp Wed Jun 12 21:46:14 2013
>> @@ -3024,7 +3024,7 @@ bool Expr::hasNonTrivialCall(ASTContext
>> Expr::NullPointerConstantKind
>> Expr::isNullPointerConstant(ASTContext &Ctx,
>>                             NullPointerConstantValueDependence NPC) const {
>> -  if (isValueDependent()) {
>> +  if (isValueDependent() && !Ctx.getLangOpts().CPlusPlus11) {
>>     switch (NPC) {
>>     case NPC_NeverValueDependent:
>>       llvm_unreachable("Unexpected value dependent expression!");
>> @@ -3085,7 +3085,8 @@ Expr::isNullPointerConstant(ASTContext &
>>     return NPCK_CXX11_nullptr;
>>
>>   if (const RecordType *UT = getType()->getAsUnionType())
>> -    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
>> +    if (!Ctx.getLangOpts().CPlusPlus11 &&
>> +        UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
>>       if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
>>         const Expr *InitExpr = CLE->getInitializer();
>>         if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
>> @@ -3096,14 +3097,14 @@ Expr::isNullPointerConstant(ASTContext &
>>       (Ctx.getLangOpts().CPlusPlus && getType()->isEnumeralType()))
>>     return NPCK_NotNull;
>>
>> -  // If we have an integer constant expression, we need to *evaluate* it and
>> -  // test for the value 0. Don't use the C++11 constant expression semantics
>> -  // for this, for now; once the dust settles on core issue 903, we might only
>> -  // allow a literal 0 here in C++11 mode.
>>   if (Ctx.getLangOpts().CPlusPlus11) {
>> -    if (!isCXX98IntegralConstantExpr(Ctx))
>> -      return NPCK_NotNull;
>> +    // C++11 [conv.ptr]p1: A null pointer constant is an integer literal with
>> +    // value zero or a prvalue of type std::nullptr_t.
>> +    const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);
>> +    return (Lit && !Lit->getValue()) ? NPCK_ZeroLiteral : NPCK_NotNull;
>>   } else {
>> +    // If we have an integer constant expression, we need to *evaluate* it and
>> +    // test for the value 0.
>>     if (!isIntegerConstantExpr(Ctx))
>>       return NPCK_NotNull;
>>   }
>>
>> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183883&r1=183882&r2=183883&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Jun 12 21:46:14 2013
>> @@ -769,15 +769,22 @@ static_assert(&ok2 == pok2, "");
>> static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
>> static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
>>
>> -constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}
>> +// Core issue 903: we do not perform constant evaluation when checking for a
>> +// null pointer in C++11. Just check for an integer literal with value 0.
>> +constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}}
>> +constexpr Base *nullB1 = 0;
>> static_assert((Bottom*)nullB == 0, "");
>> static_assert((Derived*)nullB == 0, "");
>> static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
>> -Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
>> -Base * nullB3 = (0);
>> -// We suppress the warning in unevaluated contexts to workaround some gtest
>> -// behavior. Once this becomes an error this isn't a problem anymore.
>> -static_assert(nullB == (1 - 1), "");
>> +Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}}
>> +Base *nullB3 = (0);
>> +Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}}
>> +Base *nullB5 = ((0ULL));
>> +Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}}
>> +enum Null { kNull };
>> +Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}}
>> +static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}}
>> +
>>
>>
>> namespace ConversionOperators {
>>
>> Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=183883&r1=183882&r2=183883&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Wed Jun 12 21:46:14 2013
>> @@ -109,27 +109,30 @@ namespace PR12031 {
>>   }
>> }
>>
>> -namespace NullPtr {
>> +namespace Array {
>>   int &f(int *p);
>>   char &f(...);
>>   void g() {
>> -    int n = 0;
>> +    int n = -1;
>>     [=] {
>> -      char &k = f(n); // not a null pointer constant
>> +      int arr[n]; // VLA
>>     } ();
>>
>> -    const int m = 0;
>> -    [=] {
>> -      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
>> +    const int m = -1;
>> +    [] {
>> +      int arr[m]; // expected-error{{negative size}}
>> +    } ();
>> +
>> +    [&] {
>> +      int arr[m]; // expected-error{{negative size}}
>>     } ();
>>
>> -    [=] () -> bool {
>> -      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
>> -      return &m == 0;
>> +    [=] {
>> +      int arr[m]; // expected-error{{negative size}}
>>     } ();
>>
>>     [m] {
>> -      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
>> +      int arr[m]; // expected-error{{negative size}}
>>     } ();
>>   }
>> }
>>
>>
>> _______________________________________________
>> 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