Polyspace 代码注解实战指南:隐藏已知或可接受的静态分析结果
适用版本:R2026b
适用范围:Polyspace Bug Finder / Code Prover / Polyspace Access / Polyspace as You Code / Simulink 模块级注解
在嵌入式软件静态分析中,Polyspace 会报出大量缺陷、编码违规和运行时错误。其中一部分问题经过人工审查后,属于已知、可接受或不计划修复 的项。与其每次分析都重复处理,不如直接在源码中添加代码注解(Code Annotation),明确表达"已审查、无需处理"的态度,让后续分析自动隐藏这些结果。
本文系统整理 Polyspace 代码注解的语法、字段含义、典型用法与常见陷阱,方便日常查阅。
目录
- 一、代码注解能做什么、不能做什么
- 二、注解语法基础
- 三、为单行代码添加注解
- [3.1 最简形式](#3.1 最简形式)
- [3.2 带状态、严重性与注释](#3.2 带状态、严重性与注释)
- 四、为代码块添加注解
- [4.1 多行范围注解(
+n)](#4.1 多行范围注解(+n)) - [4.2 代码块注解(
polyspace-begin/polyspace-end)](#4.2 代码块注解(polyspace-begin / polyspace-end))
- [4.1 多行范围注解(
- 五、对同一行的多个结果进行申述
- [5.1 同一族别,多个结果名称(逗号分隔)](#5.1 同一族别,多个结果名称(逗号分隔))
- [5.2 不同族别,多个族别(空格分隔)](#5.2 不同族别,多个族别(空格分隔))
- 六、注解字段详解
- [6.1 Family 允许的取值](#6.1 Family 允许的取值)
- [6.2 Result_name 说明](#6.2 Result_name 说明)
- [6.3 Status 允许的取值](#6.3 Status 允许的取值)
- [6.4 Severity 允许的取值](#6.4 Severity 允许的取值)
- [6.5 Comment](#6.5 Comment)
- 七、典型示例
- [7.1 隐藏单个缺陷](#7.1 隐藏单个缺陷)
- [7.2 申述编码标准违规(CERT-C)](#7.2 申述编码标准违规(CERT-C))
- [7.3 隐藏多行上所有 MISRA C:2012 违规](#7.3 隐藏多行上所有 MISRA C:2012 违规)
- [7.4 隐藏函数上所有代码度量](#7.4 隐藏函数上所有代码度量)
- [7.5 同一注解指定多个族别](#7.5 同一注解指定多个族别)
- [7.6 同一注解指定多个结果名称](#7.6 同一注解指定多个结果名称)
- [7.7 申述全局变量使用情况](#7.7 申述全局变量使用情况)
- [7.8 为不同结果添加不同注释](#7.8 为不同结果添加不同注释)
- [7.9 自定义状态 / 严重性](#7.9 自定义状态 / 严重性)
- [7.10 对代码块中的违规进行申述](#7.10 对代码块中的违规进行申述)
- [7.11 对拼接行中的结果进行注解](#7.11 对拼接行中的结果进行注解)
- 八、代码注解警告与常见陷阱
- [8.1 常见触发原因](#8.1 常见触发原因)
- [8.2 其他易错点](#8.2 其他易错点)
- 九、小结
一、代码注解能做什么、不能做什么
能做什么:
- 对 Bug Finder 缺陷(DEFECT)、编码标准违规(MISRA、CERT、CWE、AUTOSAR 等)、代码度量、全局变量结果进行申述;
- 在后续分析中自动隐藏状态为
Justified、No action planned、Not a defect的结果; - 将审查结论(状态、严重性、注释)持久化到源码中,随代码一起版本管理。
不能做什么:
⚠️ 即使使用代码注解,也无法在源代码中隐藏 Code Prover 检测到的运行时错误(RTE)。
但运行时错误相关的审查信息仍会从注解中提取,并与结果一同显示。
二、注解语法基础
注解语法不区分大小写,支持两种注释风格:
- C 风格:
/* ... */ - C++ 风格:
// ...
注解以关键字 polyspace 开头,必须 包含 Family 和 Result_name 两个字段,可选 Status、Severity、Comment。
通用格式:
c
polyspace Family:Result_name [Status:Severity] "Comment"
冒号两侧可以加空格提高可读性。
三、为单行代码添加注解
3.1 最简形式
c
var++; /* polyspace DEFECT : INT_OVFL */
DEFECT是族别(Family)INT_OVFL是结果名称(Result_name)- 未指定状态时,Polyspace 默认按
No action planned处理,并在后续分析中隐藏该结果。
3.2 带状态、严重性与注释
c
var++; /* polyspace DEFECT:INT_OVFL [Justified:Low] "Overflow taken into account." */
Justified:状态Low:严重性"Overflow taken into account.":注释
四、为代码块添加注解
4.1 多行范围注解(+n)
注解作用于当前行及其后 n 行(行计数包含代码行、注释行和空行):
c
4. line of code; // polyspace +3 MISRA2012:*
5. //comment
6.
7. line of code;
8. line of code;
上例中注解覆盖第 4 行到第 7 行。
4.2 代码块注解(polyspace-begin / polyspace-end)
c
/* polyspace-begin Family : Result_name */
{
block of code
}
/* polyspace-end Family : Result_name */
关键要点:
- 注解仅适用于代码块本身 ,不作用于从代码块中调用的函数体;
- 若相同 Family/Result_name 的注解发生嵌套 ,以最内层注解为准;
- 多行代码注解不适用于绿色检查(green checks),重新分析时这些绿色检查不会被视为已申述,其 Status/Severity 也不会变更。
嵌套示例(第 9 行注解覆盖第 7 行的块注解):
c
1 /*polyspace-begin MISRA-C : 14.9 [To fix:High] */
2 int main(void)
3 {
4 int x = 1;
5 int y = x / 2;
6
7 if (y < 0) /* Block annotation is applied to this violation of MISRA-C:14.9*/
8 y++;
9 if (x > y) /*polyspace MISRA-C : 14.9 [Justified:Low] */
10 return x;
11 return x;
12 }
13 /*polyspace-end MISRA-C : 14.9 [To fix:High] "Block annotation"*/
五、对同一行的多个结果进行申述
5.1 同一族别,多个结果名称(逗号分隔)
c
line of code; /* polyspace Family : Result_1_name,Result_2_name */
5.2 不同族别,多个族别(空格分隔)
c
line of code; /* polyspace Family_1 : Result_1_name Family_2 : Result_2_name */
同样可选附加 Status、Severity、Comment。
六、注解字段详解
| 字段 | 说明 |
|---|---|
| Family | 分析结果类型,见下表 |
| Result_name | 具体检查项名称或规则编号 |
| Status | 处理状态,决定是否隐藏结果 |
| Severity | 严重性级别 |
| Comment | 附加说明文本 |
6.1 Family 允许的取值
| Family | 含义 |
|---|---|
DEFECT |
Polyspace Bug Finder 缺陷 |
RTE |
运行时检查(Code Prover) |
CODE-METRICS |
函数级代码复杂度度量 |
VARIABLE |
全局变量(Code Prover),Result_name 仅允许 * |
MISRA-C / MISRA2004 |
MISRA C:2004(根据映射也适用于 MISRA C:2012) |
MISRA-AC-AGC |
适用于生成代码的 MISRA C:2004 |
MISRA-C3 / MISRA2012 |
MISRA C:2012(对生成代码同样有效) |
MISRA-C-2023 |
MISRA C:2023 |
CERT-C |
CERT C 编码标准 |
CERT-CPP |
CERT C++ 编码标准 |
CWE |
常见弱点枚举(CWE) |
ISO-17961 |
ISO/IEC TS 17961 |
MISRA-CPP |
MISRA C++:2008 |
MISRA-CPP-2023 |
MISRA C++:2023 |
AUTOSAR-CPP14 |
AUTOSAR C++14 |
JSF |
JSF++ |
GUIDELINE |
软件复杂度规范 |
CUSTOM |
自定义编码违规 |
StandardID |
用户定义编码标准(SARIF 中 runs/taxonomies/properties/id 的短名) |
* |
通配所有分析结果 |
6.2 Result_name 说明
- DEFECT :检查项短名(如
INT_OVFL、BAD_FREE、UNSAFE_SYSTEM_CALL) - RTE :运行时检查短名(如
OVFL、IDP) - CODE-METRICS :代码复杂度度量短名;工程级和文件级度量无法通过代码注解申述
- VARIABLE :唯一允许值为
* - 编码标准 :规则编号(如
STR31-C、17.*) - 用户定义标准 :规范 ID(来自 SARIF 的
taxa元素) - 软件复杂度:规范缩写
- 支持星号通配 ,如
MISRA2012:17.*、DEFECT:*
6.3 Status 允许的取值
| Status | 是否隐藏结果 |
|---|---|
Unreviewed |
否 |
To investigate |
否 |
To fix |
否 |
Justified |
✅ 是 |
No action planned |
✅ 是 |
Not a defect |
✅ 是 |
Other |
否 |
若指定的状态不在允许范围内,Polyspace 会将其存储为自定义状态。
6.4 Severity 允许的取值
Unset、High、Medium、Low
若指定的严重性非法,会被追加到状态字段 ,作为自定义状态存储。
例如
[To investigate:sporadic]在 UI 中会显示为"待调查偶发情况"。
6.5 Comment
- 填充结果列表窗格的"注释"列;
- 可跨多行;报告呈现时每行首尾空格会合并为单个空格,作为段落阅读。
七、典型示例
7.1 隐藏单个缺陷
c
int var = INT_MAX;
var++; /* polyspace DEFECT : INT_OVFL */
未指定状态 → 默认 No action planned → 后续分析中隐藏。
7.2 申述编码标准违规(CERT-C)
c
line of code; /* polyspace CERT-C : STR31-C [Justified:Low] "Overflow cannot happen
because of external constraints." */
7.3 隐藏多行上所有 MISRA C:2012 违规
c
4. line of code ; // polyspace +3 MISRA2012:*
5. //comment
6.
7. line of code;
8. line of code;
7.4 隐藏函数上所有代码度量
注解必须放在函数定义中与函数名相同的行:
c
char func(char param) { //polyspace CODE-METRICS:*
...
}
7.5 同一注解指定多个族别
c
line of code; /* polyspace MISRA2012 : 17.* RTE : * */
覆盖 MISRA C:2012 规则 17 全部内容及所有运行时检查。
7.6 同一注解指定多个结果名称
c
system("rm ~/.config"); /* polyspace DEFECT:UNSAFE_SYSTEM_CALL,RETURN_NOT_CHECKED */
7.7 申述全局变量使用情况
c
int var; /* polyspace VARIABLE:* [Justified: Low] "Storage repo for later use" */
7.8 为不同结果添加不同注释
解析注解时,Polyspace 会忽略双引号文本之后的所有内容 。如需对多组结果分别添加注释,需重复输入 polyspace 关键字:
c
line of code; /* polyspace DEFECT:* "Defect comment" polyspace MISRA2004:5.2 "MISRA comment" */
为所有结果提供相同注释:
c
line of code; /* polyspace DEFECT : BAD_FREE MISRA2004:* "Comment for defect and MISRA" */
7.9 自定义状态 / 严重性
c
// Set Status only
line of code; /* polyspace DEFECT:* [To fix] "some comment" */
// Set Status 'To fix' and Severity 'High'
line of code; /* polyspace VARIABLE:* [To fix: High] "some comment" */
// Set custom status 'Assigned' and Severity 'Medium'
line of code; /* polyspace MISRA2012:12.* [Assigned: Medium] */
7.10 对代码块中的违规进行申述
c
double foo(void){
constexpr int speedLimit = 65;
constexpr double coeff = 0.2;
int flag{0};
int negOne{-1};
//...
return (flag)?speedLimit*coeff*negOne
: speedLimit*coeff*negOne - 35; //Noncompliant
}
int main(){
/* polyspace-begin AUTOSAR-CPP14:A5-1-1 [Justified: Low]"Known Constant"*/
//....
for(int i = 0; i<10;++i){
foo();
//...
}
/* polyspace-end AUTOSAR-CPP14:A5-1-1 [Justified: Low]"Known Constant"*/
return 1;
}
注意: for 循环的违规被申述;但 foo() 函数体内的返回语句违规不受影响,仍显示为未审查缺陷------因为块注解不延伸至被调用函数体。
7.11 对拼接行中的结果进行注解
c
#include <stdio.h>
#define NULL_PTR ((void*)0)
extern int *value;
extern int *ptr[10];
void callfoo(int **);
void t1(int val) {
callfoo(&value);
/* polyspace +1 RTE:OVFL */
printf("Dereferenced value: %d %d %d %d\n", NULL_PTR, *ptr[val], *value+val, \
val);
}
拼接行中的运行时检查溢出在后续审查中将被隐藏。
八、代码注解警告与常见陷阱
当注解有误或不再适用时,分析日志会提示:
Warning: These Polyspace annotations do not apply to the current code
8.1 常见触发原因
① 问题已不再被检测到
代码修复或分析配置变化导致问题消失,注解"悬空"。
例如:
c
/* polyspace RTE:IDP [No action planned:Low] */
当 IDP(非法解引用指针)检查原本为红色/橙色,现在变为绿色,该注解即不再适用。
② 注解语法有误
以 polyspace 开头、后跟一个单词和一个冒号的注解,会被视为申述注解。若该单词不是合法的 Family(如 DEFECT、RTE),分析将报无效警告:
c
// polyspace TODO: Fix in March dev cycle ⚠️ 会触发警告
8.2 其他易错点
| 陷阱 | 说明 |
|---|---|
| 多行注解与绿色检查 | 多行注解对绿色检查不生效,Status/Severity 不会变更 |
| 块注解与函数体 | 块注解不作用于被调用函数体 |
| 嵌套注解 | 同 Family/Result_name 时以最内层为准 |
| 多组注释 | 双引号后内容会被忽略,需重新写 polyspace 关键字 |
| 工程/文件度量 | 无法通过代码注解申述 |
九、小结
Polyspace 代码注解是一套轻量、可版本化、与源码同源的结果申述机制。掌握以下三点即可覆盖绝大多数场景:
- 语法骨架 :
polyspace Family:Result_name [Status:Severity] "Comment"; - 作用范围 :单行用
+n或直接写在行尾,代码块用polyspace-begin/polyspace-end; - 隐藏规则 :只有
Justified、No action planned、Not a defect三种状态会让结果在后续分析中隐藏。
把"审查结论"写在代码旁边,既能减少重复审查成本,又能让审查历史随代码一起留痕,是团队协作中值得推广的实践。
参考:Polyspace R2026b 官方文档 "为代码添加注解并隐藏已知或可接受的结果"。