summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorArtyom Skrobov <Artyom.Skrobov@arm.com>2014-01-24 11:10:39 +0000
committerArtyom Skrobov <Artyom.Skrobov@arm.com>2014-01-24 11:10:39 +0000
commit9f2134402c08e6d08c2e0f7a017afea2c7efe21b (patch)
treecd0a2cb26457e98cf2fcc9158c8c19be452a519b /clang/lib/Sema/SemaChecking.cpp
parent99afd96703b6943cfd98cf7543ff2f1b9db40241 (diff)
downloadbcm5719-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.cpp27
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) ---------------===//
OpenPOWER on IntegriCloud