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