r260360 - [Sema] Issue a warning for integer overflow in nested struct initializer

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 9 22:06:07 PST 2016


Author: ahatanak
Date: Wed Feb 10 00:06:06 2016
New Revision: 260360

URL: http://llvm.org/viewvc/llvm-project?rev=260360&view=rev
Log:
[Sema] Issue a warning for integer overflow in nested struct initializer

r257357 fixed clang to warn on integer overflow in struct initializers.
However, it didn't warn when a struct had a nested initializer. This
commit makes changes in Sema::CheckForIntOverflow to handle nested
initializers.

For example:

struct s {
  struct t {
    unsigned x;
  } t;
} s = {
  {
    .x = 4 * 1024 * 1024 * 1024
  }
};

rdar://problem/23526454

Modified:
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=260360&r1=260359&r2=260360&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Feb 10 00:06:06 2016
@@ -8123,12 +8123,20 @@ void Sema::CheckBoolLikeConversion(Expr
 /// Diagnose when expression is an integer constant expression and its evaluation
 /// results in integer overflow
 void Sema::CheckForIntOverflow (Expr *E) {
-  if (isa<BinaryOperator>(E->IgnoreParenCasts()))
-    E->IgnoreParenCasts()->EvaluateForOverflow(Context);
-  else if (auto InitList = dyn_cast<InitListExpr>(E))
-    for (Expr *E : InitList->inits())
-      if (isa<BinaryOperator>(E->IgnoreParenCasts()))
-        E->IgnoreParenCasts()->EvaluateForOverflow(Context);
+  // Use a work list to deal with nested struct initializers.
+  SmallVector<Expr *, 2> Exprs(1, E);
+
+  do {
+    Expr *E = Exprs.pop_back_val();
+
+    if (isa<BinaryOperator>(E->IgnoreParenCasts())) {
+      E->IgnoreParenCasts()->EvaluateForOverflow(Context);
+      continue;
+    }
+
+    if (auto InitList = dyn_cast<InitListExpr>(E))
+      Exprs.append(InitList->inits().begin(), InitList->inits().end());
+  } while (!Exprs.empty());
 }
 
 namespace {

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=260360&r1=260359&r2=260360&view=diff
==============================================================================
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Wed Feb 10 00:06:06 2016
@@ -153,3 +153,23 @@ struct s {
   .y = 5,
   .x = 4 * 1024 * 1024 * 1024  // expected-warning {{overflow in expression; result is 0 with type 'int'}}
 };
+
+struct s2 {
+  unsigned a0;
+
+  struct s3 {
+    unsigned a2;
+
+    struct s4 {
+      unsigned a4;
+    } a3;
+  } a1;
+} s2 = {
+  .a0 = 4 * 1024 * 1024 * 1024, // expected-warning {{overflow in expression; result is 0 with type 'int'}}
+  {
+    .a2 = 4 * 1024 * 1024 * 1024, // expected-warning {{overflow in expression; result is 0 with type 'int'}}
+    {
+      .a4 = 4 * 1024 * 1024 * 1024 // expected-warning {{overflow in expression; result is 0 with type 'int'}}
+    }
+  }
+};




More information about the cfe-commits mailing list