diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2016-02-10 06:06:06 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2016-02-10 06:06:06 +0000 |
commit | dfe2156f1b6e7a0374a52e9ed8838d452d14438c (patch) | |
tree | 8be243e62c9b25f5a455471c8a15dbb05adf97cb | |
parent | 08499a0110c4a8a168920e4291cbb994858cd3b3 (diff) | |
download | bcm5719-llvm-dfe2156f1b6e7a0374a52e9ed8838d452d14438c.tar.gz bcm5719-llvm-dfe2156f1b6e7a0374a52e9ed8838d452d14438c.zip |
[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
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 20 | ||||
-rw-r--r-- | clang/test/Sema/integer-overflow.c | 20 |
2 files changed, 34 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 9c3f721ca63..3b41a50609d 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8123,12 +8123,20 @@ void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) { /// 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 { diff --git a/clang/test/Sema/integer-overflow.c b/clang/test/Sema/integer-overflow.c index db5c1f4c711..02d99b3fc5c 100644 --- a/clang/test/Sema/integer-overflow.c +++ b/clang/test/Sema/integer-overflow.c @@ -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'}} + } + } +}; |