From ef44bfb9d0f15ba0391f8346c9f01355fb450a09 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 17 Mar 2008 21:11:24 +0000 Subject: [PATCH] Added initial transfer function support for inline asm. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48466 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/GRExprEngine.h | 13 ++++ lib/Analysis/GRExprEngine.cpp | 62 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 4e50745e22..9e83f5cd1f 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -365,6 +365,19 @@ protected: /// other functions that handle specific kinds of statements. void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst); + /// VisitAsmStmt - Transfer function logic for inline asm. + void VisitAsmStmt(AsmStmt* A, NodeTy* Pred, NodeSet& Dst); + + void VisitAsmStmtHelperOutputs(AsmStmt* A, + AsmStmt::outputs_iterator I, + AsmStmt::outputs_iterator E, + NodeTy* Pred, NodeSet& Dst); + + void VisitAsmStmtHelperInputs(AsmStmt* A, + AsmStmt::inputs_iterator I, + AsmStmt::inputs_iterator E, + NodeTy* Pred, NodeSet& Dst); + /// VisitBinaryOperator - Transfer function logic for binary operators. void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index f1108df405..cc0923e796 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1013,6 +1013,68 @@ void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { Visit(Ex, Pred, Dst); } +void GRExprEngine::VisitAsmStmt(AsmStmt* A, NodeTy* Pred, NodeSet& Dst) { + VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst); +} + +void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A, + AsmStmt::outputs_iterator I, + AsmStmt::outputs_iterator E, + NodeTy* Pred, NodeSet& Dst) { + if (I == E) { + VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst); + return; + } + + NodeSet Tmp; + VisitLVal(*I, Pred, Tmp); + + ++I; + + for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) + VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst); +} + +void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A, + AsmStmt::inputs_iterator I, + AsmStmt::inputs_iterator E, + NodeTy* Pred, NodeSet& Dst) { + if (I == E) { + + // We have processed both the inputs and the outputs. All of the outputs + // should evaluate to LVals. Nuke all of their values. + + // FIXME: Some day in the future it would be nice to allow a "plug-in" + // which interprets the inline asm and stores proper results in the + // outputs. + + ValueState* St = GetState(Pred); + + for (AsmStmt::outputs_iterator OI = A->begin_outputs(), + OE = A->end_outputs(); OI != OE; ++OI) { + + RVal X = GetLVal(St, *OI); + + assert (!isa(X)); + + if (isa(X)) + St = SetRVal(St, cast(X), UnknownVal()); + } + + Nodify(Dst, A, Pred, St); + return; + } + + NodeSet Tmp; + Visit(*I, Pred, Tmp); + + ++I; + + for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) + VisitAsmStmtHelperInputs(A, I, E, *NI, Dst); +} + + void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, GRExprEngine::NodeTy* Pred, GRExprEngine::NodeSet& Dst) { -- 2.40.0