[PATCH] D31839: make -Winteger-overflow find overflows in function arguments

Nick Lewycky via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 30 19:04:14 PDT 2017


nlewycky updated this revision to Diff 97253.
nlewycky added a comment.

Use an RAII object to always evaluate the arguments, except if HandleFunctionCall does it.


https://reviews.llvm.org/D31839

Files:
  lib/AST/ExprConstant.cpp
  test/Sema/integer-overflow.c


Index: test/Sema/integer-overflow.c
===================================================================
--- test/Sema/integer-overflow.c
+++ test/Sema/integer-overflow.c
@@ -151,6 +151,14 @@
   uint64_t *b;
   uint64_t b2 = b[4608 * 1024 * 1024] + 1;
 
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}} 
+  f0(4608 * 1024 * 1024);
+  f0(4608ul * 1024 * 1024);
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}} 
+  f1(4608 * 1024 * 1024, 4608 * 1024 * 1024);
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}} 
+  f2(4608 * 1024 * 1024, 4608 * 1024 * 1024);
+
 // expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
   int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
 
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4579,15 +4579,32 @@
   }
 
   bool handleCallExpr(const CallExpr *E, APValue &Result,
-                     const LValue *ResultSlot) {
+                      const LValue *ResultSlot) {
     const Expr *Callee = E->getCallee()->IgnoreParens();
     QualType CalleeType = Callee->getType();
 
     const FunctionDecl *FD = nullptr;
     LValue *This = nullptr, ThisVal;
     auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs());
     bool HasQualifier = false;
 
+    struct EvaluateIgnoredRAII {
+    public:
+      EvaluateIgnoredRAII(EvalInfo &Info, llvm::ArrayRef<const Expr*> ToEval)
+          : Info(Info), ToEval(ToEval) {}
+      ~EvaluateIgnoredRAII() {
+        if (Info.noteFailure()) {
+          for (auto E : ToEval)
+            EvaluateIgnoredValue(Info, E);
+        }
+      }
+      void cancel() { ToEval = {}; }
+      void drop_front() { ToEval = ToEval.drop_front(); }
+    private:
+      EvalInfo &Info;
+      llvm::ArrayRef<const Expr*> ToEval;
+    } EvalArguments(Info, Args);
+
     // Extract function decl and 'this' pointer from the callee.
     if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
       const ValueDecl *Member = nullptr;
@@ -4637,10 +4654,12 @@
         if (Args.empty())
           return Error(E);
 
-        if (!EvaluateObjectArgument(Info, Args[0], ThisVal))
+        const Expr *FirstArg = Args[0];
+        Args = Args.drop_front();
+        EvalArguments.drop_front();
+        if (!EvaluateObjectArgument(Info, FirstArg, ThisVal))
           return false;
         This = &ThisVal;
-        Args = Args.slice(1);
       } else if (MD && MD->isLambdaStaticInvoker()) {   
         // Map the static invoker for the lambda back to the call operator.
         // Conveniently, we don't have to slice out the 'this' argument (as is
@@ -4692,8 +4711,12 @@
     const FunctionDecl *Definition = nullptr;
     Stmt *Body = FD->getBody(Definition);
 
-    if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) ||
-        !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info,
+    if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
+      return false;
+
+    EvalArguments.cancel();
+
+    if (!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info,
                             Result, ResultSlot))
       return false;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31839.97253.patch
Type: text/x-patch
Size: 3368 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170501/b566891d/attachment.bin>


More information about the cfe-commits mailing list