diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-09-16 23:30:39 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-09-16 23:30:39 +0000 |
commit | d8e3ac318520a98f61c8f3d73f4f2d92b4b56d53 (patch) | |
tree | 2552a271a770dd447aadc7383f6333cd6dae2abe /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 96dd3635bff94fcce82a166b1114b6fe8c3746e3 (diff) | |
download | bcm5719-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.cpp | 23 |
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 |