]> granicus.if.org Git - clang/commitdiff
[Sema] Emit -Winteger-overflow for arguments in function calls, ObjC messages.
authorVolodymyr Sapsai <vsapsai@apple.com>
Tue, 27 Mar 2018 21:29:05 +0000 (21:29 +0000)
committerVolodymyr Sapsai <vsapsai@apple.com>
Tue, 27 Mar 2018 21:29:05 +0000 (21:29 +0000)
rdar://problem/35539384

Reviewers: ahatanak, nicholas, rsmith, jkorous-apple

Reviewed By: jkorous-apple

Subscribers: cfe-commits, jkorous-apple

Differential Revision: https://reviews.llvm.org/D42938

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328671 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/integer-overflow.c
test/SemaCXX/integer-overflow.cpp
test/SemaObjC/integer-overflow.m [new file with mode: 0644]

index 8686700a05615a27550986bdaf97aa4122ba0a22..80ea1379d4d19cf925a43d6672209c566023848e 100644 (file)
@@ -10225,18 +10225,22 @@ void Sema::CheckForIntOverflow (Expr *E) {
   SmallVector<Expr *, 2> Exprs(1, E);
 
   do {
-    Expr *E = Exprs.pop_back_val();
+    Expr *OriginalE = Exprs.pop_back_val();
+    Expr *E = OriginalE->IgnoreParenCasts();
 
-    if (isa<BinaryOperator>(E->IgnoreParenCasts())) {
-      E->IgnoreParenCasts()->EvaluateForOverflow(Context);
+    if (isa<BinaryOperator>(E)) {
+      E->EvaluateForOverflow(Context);
       continue;
     }
 
-    if (auto InitList = dyn_cast<InitListExpr>(E))
+    if (auto InitList = dyn_cast<InitListExpr>(OriginalE))
       Exprs.append(InitList->inits().begin(), InitList->inits().end());
-
-    if (isa<ObjCBoxedExpr>(E))
-      E->IgnoreParenCasts()->EvaluateForOverflow(Context);
+    else if (isa<ObjCBoxedExpr>(OriginalE))
+      E->EvaluateForOverflow(Context);
+    else if (auto Call = dyn_cast<CallExpr>(E))
+      Exprs.append(Call->arg_begin(), Call->arg_end());
+    else if (auto Message = dyn_cast<ObjCMessageExpr>(E))
+      Exprs.append(Message->arg_begin(), Message->arg_end());
   } while (!Exprs.empty());
 }
 
index 44c2629ebf7bcb71f63b75a7028abfbd83682389..d66ce7ff16472ac2d43f23622e023c2f220e8b7a 100644 (file)
@@ -158,6 +158,21 @@ uint64_t check_integer_overflows(int i) {
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
 }
 
+void check_integer_overflows_in_function_calls() {
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (void)f0(4608 * 1024 * 1024);
+
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  uint64_t x = f0(4608 * 1024 * 1024);
+
+// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}}
+  uint64_t (*f0_ptr)(uint64_t) = &f0;
+  (void)(*f0_ptr)(4608 * 1024 * 1024);
+
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (void)f2(0, f0(4608 * 1024 * 1024));
+}
+
 struct s {
   unsigned x;
   unsigned y;
index 6abc95614496bd408c341dfc1d585ea9be5995d2..956ec157b3fa0440f19b6c5e9ff1599d7aa327f2 100644 (file)
@@ -169,3 +169,18 @@ uint64_t check_integer_overflows(int i) { //expected-note {{declared here}}
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
 }
+
+void check_integer_overflows_in_function_calls() {
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (void)f0(4608 * 1024 * 1024);
+
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  uint64_t x = f0(4608 * 1024 * 1024);
+
+// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}}
+  uint64_t (*f0_ptr)(uint64_t) = &f0;
+  (void)(*f0_ptr)(4608 * 1024 * 1024);
+
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (void)f2(0, f0(4608 * 1024 * 1024));
+}
diff --git a/test/SemaObjC/integer-overflow.m b/test/SemaObjC/integer-overflow.m
new file mode 100644 (file)
index 0000000..6d82e29
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -Wno-objc-root-class -fsyntax-only -verify %s
+
+@interface Foo
+@end
+
+@implementation Foo
+- (int)add:(int)a with:(int)b {
+  return a + b;
+}
+
+- (void)testIntegerOverflows {
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (void)[self add:0 with:4608 * 1024 * 1024];
+
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (void)[self add:0 with:[self add:4608 * 1024 * 1024 with:0]];
+}
+@end