Author: Bill Wendling Date: 2021-12-07T11:49:18-08:00 New Revision: c4582a689c2c74e0635309979176c7ada086f066
URL: https://github.com/llvm/llvm-project/commit/c4582a689c2c74e0635309979176c7ada086f066 DIFF: https://github.com/llvm/llvm-project/commit/c4582a689c2c74e0635309979176c7ada086f066.diff LOG: [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: https://github.com/ClangBuiltLinux/linux/issues/1521 Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D114848 Added: Modified: clang/lib/Analysis/UninitializedValues.cpp clang/test/Analysis/uninit-asm-goto.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index 67cd39728c350..a38ae34f4b811 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -591,8 +591,8 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> { if (AtPredExit == MayUninitialized) { // If the predecessor's terminator is an "asm goto" that initializes - // the variable, then it won't be counted as "initialized" on the - // non-fallthrough paths. + // the variable, then don't count it as "initialized" on the indirect + // paths. CFGTerminator term = Pred->getTerminator(); if (const auto *as = dyn_cast_or_null<GCCAsmStmt>(term.getStmt())) { const CFGBlock *fallthrough = *Pred->succ_begin(); @@ -810,13 +810,22 @@ void TransferFunctions::VisitGCCAsmStmt(GCCAsmStmt *as) { if (!as->isAsmGoto()) return; - for (const Expr *o : as->outputs()) - if (const VarDecl *VD = findVar(o).getDecl()) + ASTContext &C = ac.getASTContext(); + for (const Expr *O : as->outputs()) { + const Expr *Ex = stripCasts(C, O); + + // Strip away any unary operators. Invalid l-values are reported by other + // semantic analysis passes. + while (const auto *UO = dyn_cast<UnaryOperator>(Ex)) + Ex = stripCasts(C, UO->getSubExpr()); + + if (const VarDecl *VD = findVar(Ex).getDecl()) if (vals[VD] != Initialized) // If the variable isn't initialized by the time we get here, then we // mark it as potentially uninitialized for those cases where it's used // on an indirect path, where it's not guaranteed to be defined. vals[VD] = MayUninitialized; + } } void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) { diff --git a/clang/test/Analysis/uninit-asm-goto.cpp b/clang/test/Analysis/uninit-asm-goto.cpp index 43438dc589bef..9da21584ec864 100644 --- a/clang/test/Analysis/uninit-asm-goto.cpp +++ b/clang/test/Analysis/uninit-asm-goto.cpp @@ -57,3 +57,15 @@ int test5(int x) { indirect: return -2; } + +// test6: Expect no diagnostics. +int test6(unsigned int *x) { + unsigned int val; + + // See through casts and unary operators. + asm goto("nop" : "=r" (*(unsigned int *)(&val)) ::: indirect); + *x = val; + return 0; +indirect: + return -1; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits