Skip to content

Commit

Permalink
[analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr.
Browse files Browse the repository at this point in the history
This expression may or may not be evaluated in compile time, so tracking the
result symbol is of potential interest. However, run-time offsetof is not yet
supported by the analyzer, so for now this callback is only there to assist
future implementation.

Patch by Henry Wong!

Differential Revision: https://reviews.llvm.org/D42300

llvm-svn: 324790
  • Loading branch information
haoNoQ committed Feb 10, 2018
1 parent f3e09bd commit 4b0d160
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
12 changes: 12 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
Expand Up @@ -33,6 +33,8 @@ class AnalysisOrderChecker
check::PostStmt<ArraySubscriptExpr>,
check::PreStmt<CXXNewExpr>,
check::PostStmt<CXXNewExpr>,
check::PreStmt<OffsetOfExpr>,
check::PostStmt<OffsetOfExpr>,
check::PreCall,
check::PostCall,
check::NewAllocator,
Expand Down Expand Up @@ -91,6 +93,16 @@ class AnalysisOrderChecker
llvm::errs() << "PostStmt<CXXNewExpr>\n";
}

void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
llvm::errs() << "PreStmt<OffsetOfExpr>\n";
}

void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
llvm::errs() << "PostStmt<OffsetOfExpr>\n";
}

void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
if (isCallbackEnabled(C, "PreCall")) {
llvm::errs() << "PreCall";
Expand Down
13 changes: 10 additions & 3 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Expand Up @@ -1543,12 +1543,19 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.addNodes(Dst);
break;

case Stmt::OffsetOfExprClass:
case Stmt::OffsetOfExprClass: {
Bldr.takeNodes(Pred);
VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
ExplodedNodeSet PreVisit;
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);

ExplodedNodeSet PostVisit;
for (ExplodedNode *Node : PreVisit)
VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);

getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
Bldr.addNodes(Dst);
break;

}
case Stmt::UnaryExprOrTypeTraitExprClass:
Bldr.takeNodes(Pred);
VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
Expand Down
4 changes: 3 additions & 1 deletion clang/test/Analysis/Inputs/system-header-simulator.h
Expand Up @@ -110,4 +110,6 @@ void _Exit(int status) __attribute__ ((__noreturn__));
#ifndef NULL
#define __DARWIN_NULL 0
#define NULL __DARWIN_NULL
#endif
#endif

#define offsetof(t, d) __builtin_offsetof(t, d)
13 changes: 13 additions & 0 deletions clang/test/Analysis/offsetofexpr-callback.c
@@ -0,0 +1,13 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true %s 2>&1 | FileCheck %s
#include "Inputs/system-header-simulator.h"

struct S {
char c;
};

void test() {
offsetof(struct S, c);
}

// CHECK: PreStmt<OffsetOfExpr>
// CHECK-NEXT: PostStmt<OffsetOfExpr>

0 comments on commit 4b0d160

Please sign in to comment.