summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-17 02:09:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-17 02:09:33 +0000
commitd5695297241d71a4aa38b32562a9d465027b007b (patch)
tree4f220772b7ab2a26eedbb258ba2912fd00ff0797 /lib/Sema/SemaStmt.cpp
parentb97b819a739269d2a94a9fe08aeba2d782b188d2 (diff)
Issue a warning if a throwing operator new or operator new[] returns a null
pointer, since this invokes undefined behavior. Based on a patch by Artyom Skrobov! Handling of dependent exception specifications and some additional testcases by me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199452 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index e4fe9c324c..50a9d8111d 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2936,6 +2936,28 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+
+ // 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 (const FunctionDecl *FD = getCurFunctionDecl()) {
+ OverloadedOperatorKind Op = FD->getOverloadedOperator();
+ if (Op == OO_New || Op == OO_Array_New) {
+ const FunctionProtoType *Proto
+ = FD->getType()->castAs<FunctionProtoType>();
+ bool ReturnValueNonNull;
+
+ if (!Proto->isNothrow(Context, /*ResultIfDependent*/true) &&
+ !RetValExp->isValueDependent() &&
+ RetValExp->EvaluateAsBooleanCondition(ReturnValueNonNull,
+ Context) &&
+ !ReturnValueNonNull)
+ Diag(ReturnLoc, diag::warn_operator_new_returns_null)
+ << FD << getLangOpts().CPlusPlus11;
+ }
+ }
}
if (RetValExp) {