diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-17 02:09:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-17 02:09:33 +0000 |
commit | d5695297241d71a4aa38b32562a9d465027b007b (patch) | |
tree | 4f220772b7ab2a26eedbb258ba2912fd00ff0797 /lib/Sema/SemaStmt.cpp | |
parent | b97b819a739269d2a94a9fe08aeba2d782b188d2 (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.cpp | 22 |
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) { |