diff options
author | Artyom Skrobov <Artyom.Skrobov@arm.com> | 2014-01-24 11:10:39 +0000 |
---|---|---|
committer | Artyom Skrobov <Artyom.Skrobov@arm.com> | 2014-01-24 11:10:39 +0000 |
commit | 9f2134402c08e6d08c2e0f7a017afea2c7efe21b (patch) | |
tree | cd0a2cb26457e98cf2fcc9158c8c19be452a519b /clang/lib/Sema/SemaChecking.cpp | |
parent | 99afd96703b6943cfd98cf7543ff2f1b9db40241 (diff) | |
download | bcm5719-llvm-9f2134402c08e6d08c2e0f7a017afea2c7efe21b.tar.gz bcm5719-llvm-9f2134402c08e6d08c2e0f7a017afea2c7efe21b.zip |
Combine the checks for returns_nonnull and for operator new returning null, in Sema::CheckReturnValExpr. Add the missing handling of value-dependent expressions for returns_nonnull.
llvm-svn: 199989
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 4ebadb9cf58..dca678d5144 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -730,10 +730,9 @@ static bool CheckNonNullExpr(Sema &S, } bool Result; - if (Expr->EvaluateAsBooleanCondition(Result, S.Context) && !Result) - return true; - - return false; + return (!Expr->isValueDependent() && + Expr->EvaluateAsBooleanCondition(Result, S.Context) && + !Result); } static void CheckNonNullArgument(Sema &S, @@ -4386,7 +4385,8 @@ void Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc, bool isObjCMethod, - const AttrVec *Attrs) { + const AttrVec *Attrs, + const FunctionDecl *FD) { CheckReturnStackAddr(*this, RetValExp, lhsType, ReturnLoc); // Check if the return value is null but should not be. @@ -4400,6 +4400,23 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, << (isObjCMethod ? 1 : 0) << RetValExp->getSourceRange(); break; } + + // C++11 [basic.stc.dynamic.allocation]p4: + // If an allocation function declared with a non-throwing + // exception-specification fails to allocate storage, it shall return + // a null pointer. Any other allocation function that fails to allocate + // storage shall indicate failure only by throwing an exception [...] + if (FD) { + OverloadedOperatorKind Op = FD->getOverloadedOperator(); + if (Op == OO_New || Op == OO_Array_New) { + const FunctionProtoType *Proto + = FD->getType()->castAs<FunctionProtoType>(); + if (!Proto->isNothrow(Context, /*ResultIfDependent*/true) && + CheckNonNullExpr(*this, RetValExp)) + Diag(ReturnLoc, diag::warn_operator_new_returns_null) + << FD << getLangOpts().CPlusPlus11; + } + } } //===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===// |