summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-09-16 23:30:39 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-09-16 23:30:39 +0000
commitd8e3ac318520a98f61c8f3d73f4f2d92b4b56d53 (patch)
tree2552a271a770dd447aadc7383f6333cd6dae2abe /clang/lib/CodeGen/CodeGenFunction.cpp
parent96dd3635bff94fcce82a166b1114b6fe8c3746e3 (diff)
downloadbcm5719-llvm-d8e3ac318520a98f61c8f3d73f4f2d92b4b56d53.tar.gz
bcm5719-llvm-d8e3ac318520a98f61c8f3d73f4f2d92b4b56d53.zip
Fix a couple of wrong-code bugs in switch-on-constant optimization:
* recurse through intermediate LabelStmts and AttributedStmts when checking whether a statement inside a switch declares a variable * if the end of a compound statement is reachable from the chosen case label, and the compound statement contains a variable declaration, it's not valid to just emit the contents of the compound statement -- we must emit the statement itself or we lose the scope (and thus end lifetimes at the wrong point) llvm-svn: 281797
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 0b9fe29a9ce..1959f468318 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -25,6 +25,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
@@ -1168,6 +1169,28 @@ bool CodeGenFunction::containsBreak(const Stmt *S) {
return false;
}
+bool CodeGenFunction::mightAddDeclToScope(const Stmt *S) {
+ if (!S) return false;
+
+ // Some statement kinds add a scope and thus never add a decl to the current
+ // scope. Note, this list is longer than the list of statements that might
+ // have an unscoped decl nested within them, but this way is conservatively
+ // correct even if more statement kinds are added.
+ if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+ isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
+ isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
+ isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
+ return false;
+
+ if (isa<DeclStmt>(S))
+ return true;
+
+ for (const Stmt *SubStmt : S->children())
+ if (mightAddDeclToScope(SubStmt))
+ return true;
+
+ return false;
+}
/// ConstantFoldsToSimpleInteger - If the specified expression does not fold
/// to a constant, or if it does but contains a label, return false. If it
OpenPOWER on IntegriCloud