summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-04-15 22:38:07 +0000
committerAnna Zaks <ganna@apple.com>2013-04-15 22:38:07 +0000
commit8591aa78db0fdee7da9ea06467bda6486005a57a (patch)
treeda37f3dc9f7affa54543b3b8c31c83c67f1bab94 /clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
parent7460deb15d572fcc43f91d0ba0cebc3382b6f497 (diff)
downloadbcm5719-llvm-8591aa78db0fdee7da9ea06467bda6486005a57a.tar.gz
bcm5719-llvm-8591aa78db0fdee7da9ea06467bda6486005a57a.zip
[analyzer] Do not crash when processing binary "?:" in C++
When computing the value of ?: expression, we rely on the last expression in the previous basic block to be the resulting value of the expression. This is not the case for binary "?:" operator (GNU extension) in C++. As the last basic block has the expression for the condition subexpression, which is an R-value, whereas the true subexpression is the L-value. Note the operator evaluation just happens to work in C since the true subexpression is an R-value (like the condition subexpression). CFG is the same in C and C++ case, but the AST nodes are different, which the LValue to Rvalue conversion happening after the BinaryConditionalOperator evaluation. Changed the logic to only use the last expression from the predecessor only if it matches either true or false subexpression. Note, the logic needed fortification anyway: L and R were passed but not even used by the function. Also, change the conjureSymbolVal to correctly compute the type, when the expression is an LG-value. llvm-svn: 179574
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/SValBuilder.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 19a4353ffc0..309230ebed0 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -106,12 +106,19 @@ SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
return nonloc::SymbolVal(sym);
}
-DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
- const Expr *expr,
+DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag,
+ const Expr *Ex,
const LocationContext *LCtx,
- unsigned count) {
- QualType T = expr->getType();
- return conjureSymbolVal(symbolTag, expr, LCtx, T, count);
+ unsigned Count) {
+ QualType T = Ex->getType();
+
+ // Compute the type of the result. If the expression is not an R-value, the
+ // result should be a location.
+ QualType ExType = Ex->getType();
+ if (Ex->isGLValue())
+ T = LCtx->getAnalysisDeclContext()->getASTContext().getPointerType(ExType);
+
+ return conjureSymbolVal(SymbolTag, Ex, LCtx, T, Count);
}
DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
OpenPOWER on IntegriCloud