 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
72.2% |
13 / 18 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
88.9% |
16 / 18 |
| |
|
Line Coverage: |
100.0% |
29 / 29 |
| |
 |
|
 |
1 : //=== CastToStructChecker.cpp - Fixed address usage checker ----*- C++ -*--===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This files defines CastToStructChecker, a builtin checker that checks for
11 : // cast from non-struct pointer to struct pointer.
12 : // This check corresponds to CWE-588.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
17 : #include "GRExprEngineInternalChecks.h"
18 :
19 : using namespace clang;
20 :
21 : namespace {
22 : class CastToStructChecker
1845: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
23 1845: : public CheckerVisitor<CastToStructChecker> {
24 : BuiltinBug *BT;
25 : public:
26 1845: CastToStructChecker() : BT(0) {}
27 : static void *getTag();
28 : void PreVisitCastExpr(CheckerContext &C, const CastExpr *B);
29 : };
30 : }
31 :
32 1845: void *CastToStructChecker::getTag() {
33 : static int x;
34 1845: return &x;
35 : }
36 :
37 : void CastToStructChecker::PreVisitCastExpr(CheckerContext &C,
38 5771: const CastExpr *CE) {
39 5771: const Expr *E = CE->getSubExpr();
40 5771: ASTContext &Ctx = C.getASTContext();
41 5771: QualType OrigTy = Ctx.getCanonicalType(E->getType());
42 5771: QualType ToTy = Ctx.getCanonicalType(CE->getType());
43 :
44 5771: PointerType *OrigPTy = dyn_cast<PointerType>(OrigTy.getTypePtr());
45 5771: PointerType *ToPTy = dyn_cast<PointerType>(ToTy.getTypePtr());
46 :
3415: branch 0 taken
2356: branch 1 taken
2389: branch 2 taken
1026: branch 3 taken
47 5771: if (!ToPTy || !OrigPTy)
48 4745: return;
49 :
50 1026: QualType OrigPointeeTy = OrigPTy->getPointeeType();
51 1026: QualType ToPointeeTy = ToPTy->getPointeeType();
52 :
804: branch 2 taken
222: branch 3 taken
53 1026: if (!ToPointeeTy->isStructureType())
54 804: return;
55 :
56 : // We allow cast from void*.
100: branch 2 taken
122: branch 3 taken
57 222: if (OrigPointeeTy->isVoidType())
58 100: return;
59 :
60 : // Now the cast-to-type is struct pointer, the original type is not void*.
16: branch 2 taken
106: branch 3 taken
61 122: if (!OrigPointeeTy->isRecordType()) {
16: branch 1 taken
0: branch 2 not taken
62 16: if (ExplodedNode *N = C.GenerateNode()) {
16: branch 0 taken
0: branch 1 not taken
63 16: if (!BT)
64 : BT = new BuiltinBug("Cast from non-struct type to struct type",
65 : "Casting a non-structure type to a structure type "
66 : "and accessing a field can lead to memory access "
67 16: "errors or data corruption.");
68 16: RangedBugReport *R = new RangedBugReport(*BT,BT->getDescription(), N);
69 16: R->addRange(CE->getSourceRange());
70 16: C.EmitReport(R);
71 : }
72 : }
73 : }
74 :
75 1845: void clang::RegisterCastToStructChecker(GRExprEngine &Eng) {
76 1845: Eng.registerCheck(new CastToStructChecker());
77 1845: }
Generated: 2010-02-10 01:31 by zcov