Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
jordan_rose accepted this revision. jordan_rose added a comment. This revision is now accepted and ready to land. Let's just go with your simple version that makes the common case better. There are a lot of problems with `throw`, so I wouldn't worry about that right now. (By the way, we don't remove unreachable blocks because we want to be able to diagnose unreachable code.) http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
klimek added a comment. > I currently see the following ways forward: > > 1. Extend this patch to cover also "throw", fixing case B) > 2. Do 1) plus loop over the whole body to also fix case C) > 3. Drop this patch and instead remove unreachable blocks after the whole CFG > has been generated (by mark-and-sweep), fixing B), C) and D) How would that work in a way that we don't lose the unreachable warnings that are actually correct? http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
jordan_rose added a subscriber: dcoughlin. jordan_rose added a comment. Hm. On the one hand, getting this right seems like a nice property, and even adding another loop wouldn't change the order of growth. On the other hand, not having the extra destructors seems like the same sort of property as not having unreachable statements, and if you //do// have unreachable statements then also having unreachable destructors seems reasonably consistent. Devin, what would you think? http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre added a comment. Basically, there are the following cases: A) void f() { S s; } Everything OK, only one (reachable) destructor is generated B) int f() { S s; return 1; } In current trunk, this first generates dtor in a block when visiting the CompoundStmt, and then abandons that block when visiting the ReturnStmt. Thus we have one unreachable block just containing the dtor. C) int f() { S s; return 1; int i = 1; } Like B), but the unreachable block also contains "int i = 1". D) int f(bool b) { S s; if(b) return 1; else return 17; } Like B), but not fixed by this patch. E) Any combination of B) or D) with "throw" or a noreturn function instead of "return". Not fixed by the current patch. I think that case B) is a common thing, and thus it's handled by this patch. Handling case B) with a 'throw' instead of 'return' should be easy enough, too. C) is a bit unusual due to the unreachable statement, thus I think that we should not optimize for that corner case. D) more usual, but not easy to fix. I currently see the following ways forward: 1. Extend this patch to cover also "throw", fixing case B) 2. Do 1) plus loop over the whole body to also fix case C) 3. Drop this patch and instead remove unreachable blocks after the whole CFG has been generated (by mark-and-sweep), fixing B), C) and D) The following comment at the beginning of VisitReturnStmt() indicates that this was planned // NOTE: If a "return" appears in the middle of a block, this means that the // code afterwards is DEAD (unreachable). We still keep a basic block // for that code; a simple "mark-and-sweep" from the entry block will be // able to report such dead blocks. I'm not sure if that is actually done. http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
klimek added inline comments. Comment at: lib/Analysis/CFG.cpp:1949-1952 @@ +1948,6 @@ + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + klimek wrote: > majnemer wrote: > > mgehre wrote: > > > klimek wrote: > > > > If the body is non-empty, but the return is not the last statement, > > > > won't that still call addAutomaticObjDtors twice? > > > Yes, if there are statements after a "return" (i.e. dead code), it will > > > still call addAutomaticObjDtors twice, just like before this patch. > > > I guess that this case is not to common, and would be flagged by other > > > checks. > > Please don't use `dyn_cast` if you just need to perform a type test, use > > `isa` instead. > > You need a space between `if` and `(`. > Is there a reason to not fix that while we're here (seems like a related > issue into which somebody might run down the road otherwise?) I'd still be curious about an answer to my question :) http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
klimek added a reviewer: jordan_rose. klimek added a comment. +jordan for an opinion on whether we want to fix the more general case. My main problem is that while we're at it we need to fully understand the change anyway, and if somebody runs into this later, they'll need a long time debugging this surprising effect (like what happened to you here ;) http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre added inline comments. Comment at: lib/Analysis/CFG.cpp:1949-1952 @@ +1948,6 @@ + } + if (!C->body_empty() && !isa(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + Yes, sorry, I was busy with something else. I was reluctant to fix the more general case, because that would introduce a second loop, and may (or may not) have performance implications. On the other hand, unreachable block don't seem to have any negative impact. http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre added a comment. I see. Thinking about this, the same issue should also apply to a throw inside the compound stmt. And it's not only about suppressing the dtors but any CFG entries after return/throw. I'll prepare an updated patch. Manuel Klimekschrieb am So., 1. Nov. 2015 23:04: > klimek added a reviewer: jordan_rose. > klimek added a comment. > > +jordan for an opinion on whether we want to fix the more general case. > > My main problem is that while we're at it we need to fully understand the > change anyway, and if somebody runs into this later, they'll need a long > time debugging this surprising effect (like what happened to you here ;) > > http://reviews.llvm.org/D13973 http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre updated this revision to Diff 38359. mgehre added a comment. Update for review comments http://reviews.llvm.org/D13973 Files: lib/Analysis/CFG.cpp test/Analysis/no-unreachable-dtors.cpp Index: test/Analysis/no-unreachable-dtors.cpp === --- /dev/null +++ test/Analysis/no-unreachable-dtors.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s + +struct S { + ~S(); +}; + +// the return at the end of an CompoundStmt does not lead to an unreachable block containing the dtors +void test() { // expected-warning-re{{test -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: no | Empty WorkList: yes}} + S s; + return; +} Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if (!C->body_empty() && !isa(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); Index: test/Analysis/no-unreachable-dtors.cpp === --- /dev/null +++ test/Analysis/no-unreachable-dtors.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s + +struct S { + ~S(); +}; + +// the return at the end of an CompoundStmt does not lead to an unreachable block containing the dtors +void test() { // expected-warning-re{{test -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: no | Empty WorkList: yes}} + S s; + return; +} Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if (!C->body_empty() && !isa(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
klimek added inline comments. Comment at: lib/Analysis/CFG.cpp:1949-1952 @@ +1948,6 @@ + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + majnemer wrote: > mgehre wrote: > > klimek wrote: > > > If the body is non-empty, but the return is not the last statement, won't > > > that still call addAutomaticObjDtors twice? > > Yes, if there are statements after a "return" (i.e. dead code), it will > > still call addAutomaticObjDtors twice, just like before this patch. > > I guess that this case is not to common, and would be flagged by other > > checks. > Please don't use `dyn_cast` if you just need to perform a type test, use > `isa` instead. > You need a space between `if` and `(`. Is there a reason to not fix that while we're here (seems like a related issue into which somebody might run down the road otherwise?) http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre added inline comments. Comment at: lib/Analysis/CFG.cpp:1949-1952 @@ +1948,6 @@ + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + klimek wrote: > If the body is non-empty, but the return is not the last statement, won't > that still call addAutomaticObjDtors twice? Yes, if there are statements after a "return" (i.e. dead code), it will still call addAutomaticObjDtors twice, just like before this patch. I guess that this case is not to common, and would be flagged by other checks. http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
majnemer added a subscriber: majnemer. Comment at: lib/Analysis/CFG.cpp:1949 @@ +1948,3 @@ + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt mgehre wrote: > klimek wrote: > > If the body is non-empty, but the return is not the last statement, won't > > that still call addAutomaticObjDtors twice? > Yes, if there are statements after a "return" (i.e. dead code), it will still > call addAutomaticObjDtors twice, just like before this patch. > I guess that this case is not to common, and would be flagged by other checks. Please don't use `dyn_cast` if you just need to perform a type test, use `isa` instead. You need a space between `if` and `(`. http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
klimek added inline comments. Comment at: lib/Analysis/CFG.cpp:1949-1952 @@ +1948,6 @@ + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + If the body is non-empty, but the return is not the last statement, won't that still call addAutomaticObjDtors twice? http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre updated this revision to Diff 38090. mgehre added a comment. Fix formatting http://reviews.llvm.org/D13973 Files: lib/Analysis/CFG.cpp Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre updated this revision to Diff 38157. mgehre added a comment. Add test case http://reviews.llvm.org/D13973 Files: lib/Analysis/CFG.cpp test/Analysis/no-unreachable-dtors.cpp Index: test/Analysis/no-unreachable-dtors.cpp === --- /dev/null +++ test/Analysis/no-unreachable-dtors.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s + +struct S { + ~S(); +}; + +// the return at the end of an CompoundStmt does not lead to an unreachable block containing the dtors +void test() { // expected-warning-re{{test -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: no | Empty WorkList: yes}} + S s; + return; +} Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); Index: test/Analysis/no-unreachable-dtors.cpp === --- /dev/null +++ test/Analysis/no-unreachable-dtors.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s + +struct S { + ~S(); +}; + +// the return at the end of an CompoundStmt does not lead to an unreachable block containing the dtors +void test() { // expected-warning-re{{test -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: no | Empty WorkList: yes}} + S s; + return; +} Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +// If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
klimek added a subscriber: klimek. klimek added a comment. A test that fails before this patch and passes afterwards is needed :) If you need help writing that test, let me know. http://reviews.llvm.org/D13973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D13973: CFG: Delay creating Dtors for CompoundStmts which end in ReturnStmt
mgehre created this revision. mgehre added a reviewer: krememek. mgehre added a subscriber: cfe-commits. VisitReturnStmt would create a new block with including Dtors, so the Dtors created in VisitCompoundStmts would be in an unreachable block. Example: struct S { ~S(); } void f() { S s; return; } void g() { S s; } Before this patch, f has one additional unreachable block containing just the destructor of S. With this patch, both f and g have the same blocks. http://reviews.llvm.org/D13973 Files: lib/Analysis/CFG.cpp Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +//If the body ends with a ReturnStmt, the Dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -1942,7 +1942,15 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { - addLocalScopeAndDtors(C); + LocalScope::const_iterator scopeBeginPos = ScopePos; + if (BuildOpts.AddImplicitDtors) { +addLocalScopeForStmt(C); + } + if(!C->body_empty() && !dyn_cast(*C->body_rbegin())) { +//If the body ends with a ReturnStmt, the Dtors will be added in VisitReturnStmt +addAutomaticObjDtors(ScopePos, scopeBeginPos, C); + } + CFGBlock *LastBlock = Block; for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits