[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
llvm-svn: 260360
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9c3f721..3b41a50 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -8123,12 +8123,20 @@
/// 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 {