From: Anders Carlsson Date: Mon, 1 Dec 2008 02:13:57 +0000 (+0000) Subject: Add a new variant of isNullConstantExpr that returns an EvalResult. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=efa9b3877ef298bcb792600ac33521827e1f7faf;p=clang Add a new variant of isNullConstantExpr that returns an EvalResult. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60318 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 6623837695..29a36a1ec8 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -110,7 +110,6 @@ public: }; isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx) const; - bool isNullPointerConstant(ASTContext &Ctx) const; bool isBitField(); /// getIntegerConstantExprValue() - Return the value of an integer @@ -179,6 +178,12 @@ public: /// must be called on an expression that constant folds to an integer. llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const; + /// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an + /// integer constant expression with the value zero, or if this is one that is + /// cast to void*. + bool isNullPointerConstant(EvalResult &Result, ASTContext &Ctx) const; + bool isNullPointerConstant(ASTContext &Ctx) const; + /// hasGlobalStorage - Return true if this expression has static storage /// duration. This means that the address of this expression is a link-time /// constant. diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 3c021c262d..a4f7f8bf40 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1007,7 +1007,14 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, /// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an /// integer constant expression with the value zero, or if this is one that is /// cast to void*. -bool Expr::isNullPointerConstant(ASTContext &Ctx) const { +bool Expr::isNullPointerConstant(ASTContext &Ctx) const +{ + EvalResult EvalResult; + + return isNullPointerConstant(EvalResult, Ctx); +} + +bool Expr::isNullPointerConstant(EvalResult &Result, ASTContext &Ctx) const { // Strip off a cast to void*, if it exists. Except in C++. if (const ExplicitCastExpr *CE = dyn_cast(this)) { if (!Ctx.getLangOptions().CPlusPlus) { @@ -1017,20 +1024,20 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const { if (Pointee.getCVRQualifiers() == 0 && Pointee->isVoidType() && // to void* CE->getSubExpr()->getType()->isIntegerType()) // from int. - return CE->getSubExpr()->isNullPointerConstant(Ctx); + return CE->getSubExpr()->isNullPointerConstant(Result, Ctx); } } } else if (const ImplicitCastExpr *ICE = dyn_cast(this)) { // Ignore the ImplicitCastExpr type entirely. - return ICE->getSubExpr()->isNullPointerConstant(Ctx); + return ICE->getSubExpr()->isNullPointerConstant(Result, Ctx); } else if (const ParenExpr *PE = dyn_cast(this)) { // Accept ((void*)0) as a null pointer constant, as many other // implementations do. - return PE->getSubExpr()->isNullPointerConstant(Ctx); + return PE->getSubExpr()->isNullPointerConstant(Result, Ctx); } else if (const CXXDefaultArgExpr *DefaultArg = dyn_cast(this)) { // See through default argument expressions - return DefaultArg->getExpr()->isNullPointerConstant(Ctx); + return DefaultArg->getExpr()->isNullPointerConstant(Result, Ctx); } else if (isa(this)) { // The GNU __null extension is always a null pointer constant. return true; @@ -1042,6 +1049,9 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const { // If we have an integer constant expression, we need to *evaluate* it and // test for the value 0. + return Evaluate(Result, Ctx) && !Result.HasSideEffects && + Result.Val.isInt() && Result.Val.getInt() == 0; + llvm::APSInt Val(32); return isIntegerConstantExpr(Val, Ctx, 0, true) && Val == 0; }