in the Clang Static Analyzer dm Balogh adam.balogh@ericsson.com - - PowerPoint PPT Presentation

in the clang static
SMART_READER_LITE
LIVE PREVIEW

in the Clang Static Analyzer dm Balogh adam.balogh@ericsson.com - - PowerPoint PPT Presentation

Statistics Based Checkers in the Clang Static Analyzer dm Balogh adam.balogh@ericsson.com Euro LLVM 2019, Brussels, Belgium Ericsson 2019-04-08 Ericsson Internal | 2018-02-21 The Problem Huge legacy code with weak documentation


slide-1
SLIDE 1

Ericsson Internal | 2018-02-21

Statistics Based Checkers in the Clang Static Analyzer

Ádám Balogh adam.balogh@ericsson.com

Euro LLVM 2019, Brussels, Belgium Ericsson 2019-04-08

slide-2
SLIDE 2

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation

The Problem

slide-3
SLIDE 3

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation

The Problem

int may_return_return_negative(); // no body available

X.h

slide-4
SLIDE 4

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls

The Problem

int may_return_return_negative(); // no body available

X.h

slide-5
SLIDE 5

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls

The Problem

int may_return_return_negative(); // no body available

X.h

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y1.c

slide-6
SLIDE 6

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls

The Problem

int may_return_return_negative(); // no body available

X.h

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y1.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y2.c

slide-7
SLIDE 7

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls

The Problem

int may_return_return_negative(); // no body available

X.h

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y1.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y2.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y3.c

slide-8
SLIDE 8

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls

The Problem

int may_return_return_negative(); // no body available

X.h

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y1.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y2.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y3.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y4.c

slide-9
SLIDE 9

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls

The Problem

int may_return_return_negative(); // no body available

X.h

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y1.c

int i = may_return_return_negative(); v[i]; // error: negative indexing

Yn.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y2.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y3.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y4.c

slide-10
SLIDE 10

Ericsson Internal | 2018-02-21

— Huge legacy code with weak documentation — Many calls for may_return_negative(), return value is checked for negative in e.g. 98% of the calls — Goal: detect the 2% where the negativeness of the return value is not checked

The Problem

int may_return_return_negative(); // no body available

X.h

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y1.c

int i = may_return_return_negative(); v[i]; // error: negative indexing

Yn.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y2.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y3.c

int i = may_return_return_negative(); if (i < 0) return; v[i]; // OK.

Y4.c

slide-11
SLIDE 11

Ericsson Internal | 2018-02-21

What do we check?

Ignored Return Value

fread(data, …); // data may be garbage // if read failed

Ignored.c

Find calls where the return value is ignored but it should not

slide-12
SLIDE 12

Ericsson Internal | 2018-02-21

What do we check?

Ignored Return Value Special Return Value

int i = ret_neg(); v[i]; // error

NegRet.c

fread(data, …); // data may be garbage // if read failed

Ignored.c

Negative Integers Find calls where the return value is ignored but it should not Find calls where the integer return value is not checked for negative but it should

slide-13
SLIDE 13

Ericsson Internal | 2018-02-21

What do we check?

Ignored Return Value Special Return Value

int i = ret_neg(); v[i]; // error

NegRet.c

T *t = ret_null(); t->field; // error

NullRet.c

fread(data, …); // data may be garbage // if read failed

Ignored.c

Negative Integers Null Pointers Find calls where the return value is ignored but it should not Find calls where the integer return value is not checked for negative but it should Find calls where the pointer return value is not checked for null pointer but it should

slide-14
SLIDE 14

Ericsson Internal | 2018-02-21

What do we check?

Other “special” values may be added Ignored Return Value Special Return Value

int i = ret_neg(); v[i]; // error

NegRet.c

T *t = ret_null(); t->field; // error

NullRet.c

fread(data, …); // data may be garbage // if read failed

Ignored.c

Negative Integers Null Pointers Find calls where the return value is ignored but it should not Find calls where the integer return value is not checked for negative but it should Find calls where the pointer return value is not checked for null pointer but it should

slide-15
SLIDE 15

Ericsson Internal | 2018-02-21

How does it work?

X.c X.c X.c *.c Y.cpp Y.cpp Y.cpp *.cpp

slide-16
SLIDE 16

Ericsson Internal | 2018-02-21

How does it work?

X.c X.c X.c *.c Y.cpp Y.cpp Y.cpp *.cpp clang SA *.yaml *.yaml Phase 1: Collect statistics

slide-17
SLIDE 17

Ericsson Internal | 2018-02-21

How does it work?

X.c X.c X.c *.c Y.cpp Y.cpp Y.cpp *.cpp clang SA clang SA *.yaml *.yaml Phase 1: Collect statistics Phase 2: Analyze

slide-18
SLIDE 18

Ericsson Internal | 2018-02-21

How does it work?

— Threshold and minimum required number of calls configurable (default: 85% and 10 calls) X.c X.c X.c *.c Y.cpp Y.cpp Y.cpp *.cpp clang SA clang SA *.yaml *.yaml Phase 1: Collect statistics Phase 2: Analyze

slide-19
SLIDE 19

Ericsson Internal | 2018-02-21

How does it work?

— Threshold and minimum required number of calls configurable (default: 85% and 10 calls) — CodeChecker support exists, open sourcing planned X.c X.c X.c *.c Y.cpp Y.cpp Y.cpp *.cpp clang SA clang SA *.yaml *.yaml Phase 1: Collect statistics Phase 2: Analyze

slide-20
SLIDE 20

Ericsson Internal | 2018-02-21

Checking for Special Return Values

— No warnings, just state split

slide-21
SLIDE 21

Ericsson Internal | 2018-02-21

Checking for Special Return Values

— No warnings, just state split

int i = may_return_negative();

slide-22
SLIDE 22

Ericsson Internal | 2018-02-21

Checking for Special Return Values

— No warnings, just state split

int i = may_return_negative(); i : [INT_MIN..-1] i: [0..INT_MAX]

slide-23
SLIDE 23

Ericsson Internal | 2018-02-21

Checking for Special Return Values

— No warnings, just state split

int i = may_return_negative(); i : [INT_MIN..-1] i: [0..INT_MAX] x = v[i]; //OK. x = v[i]; //Error!

slide-24
SLIDE 24

Ericsson Internal | 2018-02-21

Checking for Special Return Values

— No warnings, just state split

int i = may_return_negative(); i : [INT_MIN..-1] i: [0..INT_MAX] x = v[i]; //OK. x = v[i]; //Error!

Reported by negative array ← indexing checker!

slide-25
SLIDE 25

Ericsson Internal | 2018-02-21

Checking for Special Return Values

— No warnings, just state split — Performance impact: low because special return value branch terminates quickly — Either by early exit or because of error

int i = may_return_negative(); i : [INT_MIN..-1] i: [0..INT_MAX] x = v[i]; //OK. x = v[i]; //Error!

Reported by negative array ← indexing checker!

slide-26
SLIDE 26

Ericsson Internal | 2018-02-21

Future Work

— False Positives: The possible return values often depend from the arguments

slide-27
SLIDE 27

Ericsson Internal | 2018-02-21

Future Work

— False Positives: The possible return values often depend from the arguments — Solution: Take the parameters also into consideration

slide-28
SLIDE 28

Thank You! adam.balogh@ericsson.com