Skip to content

Commit c4582a6

Browse files
committed
[Analysis] Ignore casts and unary ops for uninitialized values
A series of unary operators and casts may obscure the variable we're trying to analyze. Ignore them for the uninitialized value analysis. Other checks determine if the unary operators result in a valid l-value. Link: ClangBuiltLinux/linux#1521 Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D114848
1 parent 84dbfe1 commit c4582a6

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

clang/lib/Analysis/UninitializedValues.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,8 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> {
591591

592592
if (AtPredExit == MayUninitialized) {
593593
// If the predecessor's terminator is an "asm goto" that initializes
594-
// the variable, then it won't be counted as "initialized" on the
595-
// non-fallthrough paths.
594+
// the variable, then don't count it as "initialized" on the indirect
595+
// paths.
596596
CFGTerminator term = Pred->getTerminator();
597597
if (const auto *as = dyn_cast_or_null<GCCAsmStmt>(term.getStmt())) {
598598
const CFGBlock *fallthrough = *Pred->succ_begin();
@@ -810,13 +810,22 @@ void TransferFunctions::VisitGCCAsmStmt(GCCAsmStmt *as) {
810810
if (!as->isAsmGoto())
811811
return;
812812

813-
for (const Expr *o : as->outputs())
814-
if (const VarDecl *VD = findVar(o).getDecl())
813+
ASTContext &C = ac.getASTContext();
814+
for (const Expr *O : as->outputs()) {
815+
const Expr *Ex = stripCasts(C, O);
816+
817+
// Strip away any unary operators. Invalid l-values are reported by other
818+
// semantic analysis passes.
819+
while (const auto *UO = dyn_cast<UnaryOperator>(Ex))
820+
Ex = stripCasts(C, UO->getSubExpr());
821+
822+
if (const VarDecl *VD = findVar(Ex).getDecl())
815823
if (vals[VD] != Initialized)
816824
// If the variable isn't initialized by the time we get here, then we
817825
// mark it as potentially uninitialized for those cases where it's used
818826
// on an indirect path, where it's not guaranteed to be defined.
819827
vals[VD] = MayUninitialized;
828+
}
820829
}
821830

822831
void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) {

clang/test/Analysis/uninit-asm-goto.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,15 @@ int test5(int x) {
5757
indirect:
5858
return -2;
5959
}
60+
61+
// test6: Expect no diagnostics.
62+
int test6(unsigned int *x) {
63+
unsigned int val;
64+
65+
// See through casts and unary operators.
66+
asm goto("nop" : "=r" (*(unsigned int *)(&val)) ::: indirect);
67+
*x = val;
68+
return 0;
69+
indirect:
70+
return -1;
71+
}

0 commit comments

Comments
 (0)