Функции заглушки проверки, не определенные в исходном коде или выбранные для заглушки. Для упорной функции:
Проверка делает определенные допущения относительно возвращаемого значения функции и других побочных эффектов функции.
Можно точно настроить допущения, указав ограничения.
Проверка игнорирует тело функции, если оно существует. Операции в теле функции не проверяются на наличие ошибок времени выполнения.
Если проверка тела функции является неточной и вызывает множество оранжевых проверок при вызове функции, можно выбрать заглушку функции. Чтобы уменьшить количество проверок оранжевого цвета, необходимо заглушить функцию, а затем ограничить возвращаемое значение функции и указать другие побочные эффекты.
Для заглушки функций можно использовать следующие опции:
Functions to stub (-functions-to-stub): Укажите функции, которые должны быть заблокированы.
Generate stubs for Embedded Coder lookup tables (-stub-embedded-coder-lookup-table-functions): Функции-заглушки, содержащие таблицы поиска в коде, созданном в моделях с помощью Embedded Coder ®.
-code-behavior-specifications: Функции-заглушки, соответствующие стандартной функции, распознаваемой Polyspace ®.
При использовании первой опции для заглушки функции ограничение возвращаемого значения функции и моделирование других побочных эффектов выполняется путем задания ограничений. Если требуется задать ограничения с большей степенью детализации, чем ограничения, доступные в интерфейсе спецификации ограничений Polyspace, определите собственные заглушки. При использовании других опций для заглушки функций программа сама ограничивает возвращаемое значение функции и соответствующим образом моделирует ее побочные эффекты.
Проверка делает следующие предположения относительно аргументов упорных функций.
Проверка предполагает, что:
Возвращаемая функцией переменная принимает полный диапазон значений, допустимых ее типом данных.
Если функция возвращает enum переменная, значение переменной находится в диапазоне перечисления. Например, если enum тип принимает значения {0,5, -1,32}, а упорная функция имеет возвращаемый тип, проверка предполагает, что функция возвращает значения в диапазоне -1.. 32.
Если функция возвращает указатель, он не имеет значения NULL и безопасен для отмены привязки. Указатель не указывает на динамически выделенную память или другую переменную в коде.
Конкретные допущения C++: Оператор new возвращает выделенную память. Операторы, такие как operator=, operator+=, operator--(версия с префиксом) или operator<< возвращает:
Ссылка на *this, если оператор является частью определения класса.
Например, если оператор определен как:
class X {
X& operator=(const X& arg) ;
};
*this (объект, вызывающий оператор). Объект, вызывающий оператор или его элементы данных, имеют полный диапазон значений, допустимых их типом.Первый аргумент, если оператор не является частью определения класса.
Например, если оператор определен как:
X& operator+=(X& arg1, const X& arg2) ;
arg1. Объект, который arg1 ссылается на или его элементы данных имеют полный диапазон значений, разрешенных их типом. Функции, объявленные с помощью __declspec(no_return) (Visual Studio ®) или__attribute__ ((noreturn)) (GCC) не возвращаются.
Можно изменить предположения по умолчанию относительно возвращаемого значения функции.
Если функция возвращает не указывающую переменную, можно ограничить ее диапазон. Использовать опцию Constraint setup (-data-range-specifications).
С помощью интерфейса спецификации ограничений можно задать абсолютный диапазон. [. Чтобы задать более сложные ограничения, запишите заглушку функции.min..max]
Например, неопределенная функция имеет прототип:
int func(int ll, int ul);
int func(int ll, int ul) {
int ret;
assert(ret>=ll && ret <=ul);
return ret;
}Если определение func существует в вашем коде, и вы хотите переопределить определение, поскольку проверка тела функции является неточной, встроить фактическое определение и заглушку в #ifdef заявление:
#ifdef POLYSPACE
int func(int ll, int ul) {
int ret;
assert(ret>=ll && ret <=ul);
return ret;
}
#else
int func(int ll, int ul) {
/*Your function body */
}
#endifPOLYSPACE с помощью опции Preprocessor definitions (-D). При проверке вместо определения фактической функции используется заглушка.Если функция возвращает переменную указателя, можно указать, что указатель может иметь значение NULL.
Чтобы задать это предположение для всех упорных функций, используйте опцию Consider environment pointers as unsafe (-stubbed-pointers-are-unsafe).
Чтобы задать это предположение для определенных упорных функций, используйте опцию Constraint setup (-data-range-specifications).
Проверка предполагает, что:
Если аргумент является указателем, функция может записать любое значение в объект, на который указывает указатель. Диапазон значений ограничен только типом данных аргумента.
Например, в этом примере проверка предполагает, что упорная функция stubbedFunc записывает любое возможное значение в val. Поэтому утверждение оранжевое.
void stubbedFunc(int*);
void main() {
int val=0, *ptr=&val;
stubbedFunc(ptr);
assert(val==0);
}Если аргумент является указателем на структуру, функция может записать любое значение в поля структуры. Диапазон значений ограничен только типом данных полей.
В коде C++ только элементы данных первого уровня структуры могут быть записаны через указатель на структуру. Например, в этом примере анализ обладает знаниями о том, что pb->j указывает на, но не на то, что pb->pa->i указывает на. Итак, после звонка Foo, b.j отображается как инициализированный, но a.i не инициализирован.
struct A {
int i;
};
struct B {
A* pa;
int j;
};
void Foo(B*);
void main() {
A a;
B b;
b.pa = &a;
Foo(&b);
int var1 = b.j;
int var2 = a.i;
}Если аргумент является указателем на другой указатель, функция может записать в объект любое значение, на которое указывает второй указатель (только код C). Это предположение продолжается до произвольных глубин иерархии указателей.
Например, предположим, что указатель **pp указывает на другой указатель *p, который указывает на int переменная var. Если используется упорная функция **p в качестве аргумента проверка предполагает, что после вызова функции var имеет любое int значение. *p может указывать на любое место в выделенной памяти или может указывать на var но не указывает на другую переменную в коде.
Если аргумент является указателем функции, функция, на которую он указывает, вызывается (только код C).
Например, в этом примере функция упора stubbedFunc принимает указатель функции funcPtr в качестве аргумента. funcPtr указывает на func, который вызывается при звонке stubbedFunc.
typedef int (*typeFuncPtr) (int);
int func(int x){
return x;
}
int stubbedFunc(typeFuncPtr);
void main() {
typeFuncPtr funcPtr = (typeFuncPtr)(&func);
int result = stubbedFunc(funcPtr);
}Можно ограничить диапазон аргумента, передаваемого по ссылке. Использовать опцию Constraint setup (-data-range-specifications).
С помощью интерфейса спецификации ограничений можно задать абсолютный диапазон. [. Чтобы задать более сложные ограничения, запишите заглушку функции.min..max]
Например, неопределенная функция имеет прототип:
void func(int *x, int ll, int ul);
x лежит между вторым и третьим аргументами. Однако программное обеспечение предполагает полный диапазон значений *x поскольку функция не определена. Чтобы смоделировать желаемое поведение и уменьшить оранжевая проверка из неточности, напишите заглушку функции следующим образом:void func(int *x, int ll, int ul) {
assert(*x>=ll && *x <=ul);
}Если определение func существует в вашем коде, и вы хотите переопределить определение, поскольку проверка тела функции является неточной, встроить фактическое определение и заглушку в #ifdef заявление:
#ifdef POLYSPACE
void func(int *x, int ll, int ul) {
assert(*x>=ll && *x <=ul);
}
#else
void func(int *x, int ll, int ul) {
/* Your function body */
}
#endifPOLYSPACE с помощью опции Preprocessor definitions (-D). При проверке вместо определения фактической функции используется заглушка.Проверка предполагает, что заглушка функции не изменяет глобальные переменные.
Чтобы смоделировать операции записи для глобальной переменной, запишите заглушку функции.
Например, неопределенная функция имеет прототип:
void func(void);
glob. Чтобы смоделировать нужное поведение, напишите заглушку функции следующим образом:void func(void) {
volatile int randomVal;
if(randomVal)
glob = 0;
else
glob = 1;
}Если определение func существует в вашем коде, и вы хотите переопределить определение, поскольку проверка тела функции является неточной, встроить фактическое определение и заглушку в #ifdef утверждение следующим образом:
#ifdef POLYSPACE
void func(void) {
volatile int randomVal;
if(randomVal)
glob = 0;
else
glob = 1;
}
#else
void func(void) {
/* Your function body */
}
#endifPOLYSPACE использование опции Preprocessor definitions (-D). При проверке вместо определения фактической функции используется заглушка.