forked from OSchip/llvm-project
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. llvm-svn: 183883
This commit is contained in:
parent
f026b60099
commit
4055de40ab
|
@ -3024,7 +3024,7 @@ bool Expr::hasNonTrivialCall(ASTContext &Ctx) {
|
|||
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 &Ctx,
|
|||
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,
|
|||
(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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}}
|
||||
} ();
|
||||
|
||||
[=] () -> 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}}
|
||||
} ();
|
||||
|
||||
[=] {
|
||||
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}}
|
||||
} ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue