2014-05-03 15 views
23

Giả sử tôi đang làm việc với các đoạn mã C sau:Làm thế nào để theo dõi biến với máy phân tích tĩnh của Clang?

void inc(int *num) {*num++;} 
void dec(int *num) {*num--;} 

void f(int var) { 
    inc(&var); 
    dec(&var); 
} 

Bằng cách sử dụng một máy phân tích tĩnh, tôi muốn có thể cho biết nếu giá trị của var không thay đổi trong khi thực hiện của hàm. Tôi biết tôi phải tự giữ nguyên trạng thái của nó (đó là điểm viết một trình kiểm tra Clang), nhưng tôi gặp khó khăn khi lấy một tham chiếu duy nhất của biến này.

Ví dụ: nếu tôi sử dụng các API sau

void MySimpleChecker::checkPostCall(const CallEvent &Call, 
            CheckerContext &C) const { 
    SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol(); 
} 

tôi mong đợi nó để trả về một con trỏ đến đại diện của biểu tượng này trong bối cảnh kiểm tra tôi. Tuy nhiên, tôi luôn nhận được vào MyArg bằng cách sử dụng theo cách này. Điều này xảy ra cho cả hai chức năng inctháng 12 trong các cuộc gọi lại trướcđăng.

Tôi thiếu gì ở đây? Tôi đã hiểu sai về khái niệm nào?

Lưu ý: Tôi hiện đang đọc Clang CFE Internals Manual và tôi đã đọc tài liệu tuyệt vời How to Write a Checker in 24 Hours. Tôi vẫn không thể tìm thấy câu trả lời của tôi cho đến nay.

+0

Bạn có thể cung cấp thêm chi tiết về việc triển khai của mình không? Dường như không có gì sai với cách tiếp cận của bạn. Có thể triển khai của bạn có một số vấn đề. – anirudh

+0

Tôi đã sử dụng SimpleStreamChecker làm tài liệu tham khảo. Trong phương thức checkPostCall, tôi đã nhận xét hai kiểm tra "if" và họ đã sử dụng câu lệnh được cung cấp ở trên. Bạn có thể kiểm tra nó bằng cách sửa đổi xây dựng của bạn của clang và chạy kiểm tra này trong mã được cung cấp trong câu hỏi. Tôi đang sử dụng bản sửa đổi 208276. – ivarec

Trả lời

0

Tôi nghĩ bạn đã bỏ lỡ kiểm tra xem sự kiện cuộc gọi này có phải là lệnh gọi hàm inc/dec của bạn không. Bạn nên có một cái gì đó như

void MySimpleChecker::checkPostCall(const CallEvent &Call, 
           CheckerContext &C) const { 
    const IdentifierInfo* callee = Call.getCalleeIdentifier(); 
    if (callee->getName().str() == "inc" || callee->getName().str() == "dec") 
     SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol(); 
} 
+0

Điều này không hữu ích. Chỉ cần kiểm tra tên hàm của callee sẽ không thay đổi gì cả. – ivarec

Các vấn đề liên quan