r199989 - 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.
Artyom Skrobov
Artyom.Skrobov at arm.com
Fri Jan 24 03:10:40 PST 2014
Author: askrobov
Date: Fri Jan 24 05:10:39 2014
New Revision: 199989
URL: http://llvm.org/viewvc/llvm-project?rev=199989&view=rev
Log:
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.
Added:
cfe/trunk/test/SemaCXX/nonnull.cpp
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=199989&r1=199988&r2=199989&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jan 24 05:10:39 2014
@@ -7904,7 +7904,8 @@ private:
void CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
SourceLocation ReturnLoc,
bool isObjCMethod = false,
- const AttrVec *Attrs = 0);
+ const AttrVec *Attrs = 0,
+ const FunctionDecl *FD = 0);
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=199989&r1=199988&r2=199989&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Jan 24 05:10:39 2014
@@ -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
<< (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) ---------------===//
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=199989&r1=199988&r2=199989&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Jan 24 05:10:39 2014
@@ -2975,29 +2975,8 @@ Sema::ActOnReturnStmt(SourceLocation Ret
RetValExp = Res.takeAs<Expr>();
}
- CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs);
-
- // 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;
- }
- }
+ CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
+ getCurFunctionDecl());
}
if (RetValExp) {
Added: cfe/trunk/test/SemaCXX/nonnull.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nonnull.cpp?rev=199989&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/nonnull.cpp (added)
+++ cfe/trunk/test/SemaCXX/nonnull.cpp Fri Jan 24 05:10:39 2014
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int I>
+struct TS {
+ __attribute__((returns_nonnull))
+ void *value_dependent(void) {
+ return I; // no-warning
+ }
+
+ __attribute__((returns_nonnull))
+ void *value_independent(void) {
+ return 0; // expected-warning {{null returned from function that requires a non-null return value}}
+ }
+};
+
More information about the cfe-commits
mailing list