Skip to content

Commit 2a0a46f

Browse files
committed
Fix analyzer crash on 'StructuralValue'
`OpaqueValueExpr` doesn't necessarily contain a source expression. Particularly, after llvm#78041, it is used to carry the type and the value kind of a non-type template argument of floating-point type or referring to a subobject (those are so called `StructuralValue` arguments). This fixes llvm#79575.
1 parent 72fd10a commit 2a0a46f

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

clang/lib/StaticAnalyzer/Core/Environment.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ static const Expr *ignoreTransparentExprs(const Expr *E) {
4040

4141
switch (E->getStmtClass()) {
4242
case Stmt::OpaqueValueExprClass:
43-
E = cast<OpaqueValueExpr>(E)->getSourceExpr();
44-
break;
43+
if (const clang::Expr *SE = cast<OpaqueValueExpr>(E)->getSourceExpr()) {
44+
E = SE;
45+
break;
46+
} else {
47+
return E;
48+
}
4549
case Stmt::ExprWithCleanupsClass:
4650
E = cast<ExprWithCleanups>(E)->getSubExpr();
4751
break;
@@ -98,7 +102,6 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
98102
case Stmt::CXXBindTemporaryExprClass:
99103
case Stmt::ExprWithCleanupsClass:
100104
case Stmt::GenericSelectionExprClass:
101-
case Stmt::OpaqueValueExprClass:
102105
case Stmt::ConstantExprClass:
103106
case Stmt::ParenExprClass:
104107
case Stmt::SubstNonTypeTemplateParmExprClass:

clang/test/Analysis/templates.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,16 @@ namespace rdar13954714 {
6868
// force instantiation
6969
template void blockWithStatic<true>();
7070
}
71+
72+
namespace structural_value_crash {
73+
constexpr char abc[] = "abc";
74+
75+
template <const char* in>
76+
void use_template_param() {
77+
const char *p = in;
78+
}
79+
80+
void force_instantiate() {
81+
use_template_param<abc>();
82+
}
83+
}

0 commit comments

Comments
 (0)