<div dir="ltr">On Mon, Jun 17, 2013 at 9:38 AM, Jordan Rose <span dir="ltr"><<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">*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.<br>
</blockquote><div><br></div><div style>That means it breaks all programs that try to build in C++11 mode but still need to ship to 10.6 (like, say, Chromium). Can this be worked around somehow?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
*goes off to unstick internal buildbot*<br>
<span class="HOEnZb"><font color="#888888">Jordan<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
On Jun 12, 2013, at 19:46 , Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
<br>
> Author: rsmith<br>
> Date: Wed Jun 12 21:46:14 2013<br>
> New Revision: 183883<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=183883&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=183883&view=rev</a><br>
> Log:<br>
> Implement core issue 903: only integer literals with value 0 and prvalues of<br>
> type std::nullptr_t are null pointer constants from C++11 onwards.<br>
><br>
> Modified:<br>
>    cfe/trunk/lib/AST/Expr.cpp<br>
>    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
>    cfe/trunk/test/SemaCXX/lambda-expressions.cpp<br>
><br>
> Modified: cfe/trunk/lib/AST/Expr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183883&r1=183882&r2=183883&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183883&r1=183882&r2=183883&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/AST/Expr.cpp (original)<br>
> +++ cfe/trunk/lib/AST/Expr.cpp Wed Jun 12 21:46:14 2013<br>
> @@ -3024,7 +3024,7 @@ bool Expr::hasNonTrivialCall(ASTContext<br>
> Expr::NullPointerConstantKind<br>
> Expr::isNullPointerConstant(ASTContext &Ctx,<br>
>                             NullPointerConstantValueDependence NPC) const {<br>
> -  if (isValueDependent()) {<br>
> +  if (isValueDependent() && !Ctx.getLangOpts().CPlusPlus11) {<br>
>     switch (NPC) {<br>
>     case NPC_NeverValueDependent:<br>
>       llvm_unreachable("Unexpected value dependent expression!");<br>
> @@ -3085,7 +3085,8 @@ Expr::isNullPointerConstant(ASTContext &<br>
>     return NPCK_CXX11_nullptr;<br>
><br>
>   if (const RecordType *UT = getType()->getAsUnionType())<br>
> -    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())<br>
> +    if (!Ctx.getLangOpts().CPlusPlus11 &&<br>
> +        UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())<br>
>       if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){<br>
>         const Expr *InitExpr = CLE->getInitializer();<br>
>         if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))<br>
> @@ -3096,14 +3097,14 @@ Expr::isNullPointerConstant(ASTContext &<br>
>       (Ctx.getLangOpts().CPlusPlus && getType()->isEnumeralType()))<br>
>     return NPCK_NotNull;<br>
><br>
> -  // If we have an integer constant expression, we need to *evaluate* it and<br>
> -  // test for the value 0. Don't use the C++11 constant expression semantics<br>
> -  // for this, for now; once the dust settles on core issue 903, we might only<br>
> -  // allow a literal 0 here in C++11 mode.<br>
>   if (Ctx.getLangOpts().CPlusPlus11) {<br>
> -    if (!isCXX98IntegralConstantExpr(Ctx))<br>
> -      return NPCK_NotNull;<br>
> +    // C++11 [conv.ptr]p1: A null pointer constant is an integer literal with<br>
> +    // value zero or a prvalue of type std::nullptr_t.<br>
> +    const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);<br>
> +    return (Lit && !Lit->getValue()) ? NPCK_ZeroLiteral : NPCK_NotNull;<br>
>   } else {<br>
> +    // If we have an integer constant expression, we need to *evaluate* it and<br>
> +    // test for the value 0.<br>
>     if (!isIntegerConstantExpr(Ctx))<br>
>       return NPCK_NotNull;<br>
>   }<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183883&r1=183882&r2=183883&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183883&r1=183882&r2=183883&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Jun 12 21:46:14 2013<br>
> @@ -769,15 +769,22 @@ static_assert(&ok2 == pok2, "");<br>
> static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");<br>
> static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");<br>
><br>
> -constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}<br>
> +// Core issue 903: we do not perform constant evaluation when checking for a<br>
> +// null pointer in C++11. Just check for an integer literal with value 0.<br>
> +constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}}<br>
> +constexpr Base *nullB1 = 0;<br>
> static_assert((Bottom*)nullB == 0, "");<br>
> static_assert((Derived*)nullB == 0, "");<br>
> static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");<br>
> -Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}<br>
> -Base * nullB3 = (0);<br>
> -// We suppress the warning in unevaluated contexts to workaround some gtest<br>
> -// behavior. Once this becomes an error this isn't a problem anymore.<br>
> -static_assert(nullB == (1 - 1), "");<br>
> +Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}}<br>
> +Base *nullB3 = (0);<br>
> +Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}}<br>
> +Base *nullB5 = ((0ULL));<br>
> +Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}}<br>
> +enum Null { kNull };<br>
> +Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}}<br>
> +static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}}<br>
> +<br>
><br>
><br>
> namespace ConversionOperators {<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=183883&r1=183882&r2=183883&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=183883&r1=183882&r2=183883&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Wed Jun 12 21:46:14 2013<br>
> @@ -109,27 +109,30 @@ namespace PR12031 {<br>
>   }<br>
> }<br>
><br>
> -namespace NullPtr {<br>
> +namespace Array {<br>
>   int &f(int *p);<br>
>   char &f(...);<br>
>   void g() {<br>
> -    int n = 0;<br>
> +    int n = -1;<br>
>     [=] {<br>
> -      char &k = f(n); // not a null pointer constant<br>
> +      int arr[n]; // VLA<br>
>     } ();<br>
><br>
> -    const int m = 0;<br>
> -    [=] {<br>
> -      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}<br>
> +    const int m = -1;<br>
> +    [] {<br>
> +      int arr[m]; // expected-error{{negative size}}<br>
> +    } ();<br>
> +<br>
> +    [&] {<br>
> +      int arr[m]; // expected-error{{negative size}}<br>
>     } ();<br>
><br>
> -    [=] () -> bool {<br>
> -      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}<br>
> -      return &m == 0;<br>
> +    [=] {<br>
> +      int arr[m]; // expected-error{{negative size}}<br>
>     } ();<br>
><br>
>     [m] {<br>
> -      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}<br>
> +      int arr[m]; // expected-error{{negative size}}<br>
>     } ();<br>
>   }<br>
> }<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>