主要内容

本页翻译不是最新的。点击此处可查看最新英文版本。

为代码添加注解并隐藏已知或可接受的结果

如果代码的 Polyspace® 分析发现了已知或可接受的缺陷或编码违规,您可以在后续分析中隐藏这些缺陷或违规。添加代码注解,指示您已审查过这些问题,并且不打算修复它们。

您可以通过 Polyspace 用户界面(或 IDE 插件)中的菜单项添加注解,也可以直接在代码中键入注解。有关添加注解的常规工作流:

本主题展示了注解语法。

请注意,即使使用代码注解,您也无法在源代码中隐藏 Code Prover 检测到的运行时错误。然而,与所有其他结果一样,与运行时错误相关的审查信息会从相应的代码注解中提取出来,并与结果一同显示。

代码注解语法

要直接在源文件中添加注释,请使用 Polyspace 注解语法。该语法不区分大小写,且具有以下格式。/* */ 内的 C 样式注释以及以 // 开头的 C++ 样式注释均受支持。

为单个代码行添加注解

要为当前代码行(包括宏)上的结果添加注解,请使用以下语法:

line of code; /* polyspace Family:Result_name */
您可以在冒号 (:) 两侧添加空格以提高可读性。例如:
var++; /* polyspace DEFECT : INT_OVFL */

注解以关键字 polyspace 开头,并且必须包含 FamilyResult_name 字段值。

您可以选择指定 StatusSeverityComment 字段值:

polyspace Family:Result_name [Status:Severity] "Comment"

例如:

var++; /* polyspace DEFECT:INT_OVFL [Justified:Low] "Overflow taken into account."*/

如果未指定状态,Polyspace 会认为结果已申述,并为结果指定未计划任何操作状态。

有关详细信息,请参阅注解语法详细信息语法示例

为代码块添加注解

要为代码块添加注解,请使用以下语法。请注意,注解仅适用于代码块本身,不适用于从代码块中调用的函数体。

  • 对当前代码行以及随后 n 行的注解:

    line of code; /* polyspace +n Family : Result_name */

  • 代码块的注解:

    /* polyspace-begin Family : Result_name */
    {
       block of code
    }
    /* polyspace-end Family : Result_name */

(可选)指定状态、严重性和注释。

如果具有相同 FamilyResult_name 的结果的注解是嵌套的,则使用最内层的注解。

例如,在以下代码中,应用的是第 9 行的注解而非代码块注解,而代码块注解用在了第 7 行的违规上。

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"*/

为代码块添加注解时,注解仅适用于代码块内部产生的问题。例如,假设在添加了注解的代码块中有一个函数调用,而函数体引发了违规。此违规不受调用函数的代码块周围注解的影响。

有关详细信息,请参阅注解语法详细信息语法示例

对同一代码行的多个结果进行申述

如果一个代码行包含多个结果,您可以使用以下语法对这些结果进行申述:

  • 如果这些结果属于同一族别,请指定以逗号分隔的结果名称。

    line of code; /* polyspace Family : Result_1_name,Result_2_name */
  • 如果这些结果属于不同族别,请指定以空格分隔的族别名称。

    line of code; /* polyspace Family_1 : Result_1_name Family_2 : Result_2_name */

(可选)指定状态、严重性和注释。

有关详细信息,请参阅注解语法详细信息语法示例

注意

Polyspace 在解析注解时会忽略带双引号的文本之后的所有内容。要在带双引号的文本之后添加额外的注解,请再次输入 polyspace 关键字。例如:

/* polyspace Family_1 : Result_1_name "comment 1" polyspace Family_2 : Result_2_name "comment 2"*/

注解语法详细信息

要用允许的值替换不同的注解字段,请使用此表中的值,或者参阅示例

字段允许的值
Family

分析结果类型:

  • DEFECT (Polyspace Bug Finder™)

  • RTE,用于运行时检查 (Polyspace Code Prover™)

  • CODE-METRICS,用于函数级代码复杂度度量

  • VARIABLE,用于全局变量 (Polyspace Code Prover)

  • MISRA-CMISRA2004,用于检查 MISRA C™:2004 违规。根据这两个标准之间的映射关系,这些注解也适用于 MISRA C:2012 违规。这种映射关系使您在迁移到较新标准时,能够重用您针对较旧标准所给出的申述。请参阅Import Justifications from Older Standard to Newer Standard

  • MISRA-AC-AGC,检查适用于生成代码的 MISRA C:2004 违规

  • MISRA-C3MISRA2012,用于检查 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,用于检查用户定义编码标准违规。其中,StandardID 是在对用户定义编码标准进行编码的 SARIF 文件的 runs/taxonomies/properties/id 属性中指定的短名称。有关 SARIF 文件的概述,请参阅Create User-Defined Coding Standard by Using Polyspace Bug Finder Checkers

要指定所有分析结果,请使用星号字符 *:*

请参阅Syntax Examples

Result_name

对于 DEFECT,请使用检查项的短名称。请参阅Bug Finder 缺陷组和缺陷检查项的短名称

对于 RTE,请使用运行时检查的短名称。请参阅Code Prover 运行时检查的短名称 (Polyspace Code Prover)

对于 CODE-METRICS,请使用代码复杂度度量的短名称。请参阅代码复杂度度量的短名称。请注意,工程和文件度量无法通过代码注解来进行申述。

对于 VARIABLE,唯一允许的值是星号字符“*”。

对于编码标准违规,请指定规则编号。

对于用户定义的编码标准,请指定规范 ID。编码标准的每一项规范都通过使用 SARIF 文件的 run/taxonomies/taxa 数组中的条目进行编码。规范的 ID 是在相应的 taxa 元素的 id 属性中指定的。有关 SARIF 文件的概述,请参阅Create User-Defined Coding Standard by Using Polyspace Bug Finder Checkers

对于软件复杂度规范,请使用规范的缩写。请参阅规范中各个规范的相关页面。

要指定结果名称 [MISRA2012:17.*] 的所有部分或 [DEFECT:*] 族别中的所有结果名称,请使用星号字符。

请参阅Syntax Examples

Status

用于指示您打算如何处理代码中错误的文本。此值会将结果列表窗格中的状态列填充为:

  • Unreviewed

  • To investigate

  • To fix

  • Justified

  • No action planned

  • Not a defect

  • Other

Polyspace 会在后续分析中隐藏注释为 JustifiedNo action plannedNot a defect 状态的结果。如果您指定的状态不是允许的值,Polyspace 会将其存储为自定义状态。

Severity

用于指示您认为代码中的错误有多严重的文本。此值会将结果列表窗格中的严重性列填充为:

  • Unset

  • High

  • Medium

  • Low

如果您指定的严重性不是允许的值,Polyspace 会将其追加到状态字段,并将其存储为自定义状态。例如,[To investigate:sporadic]结果列表窗格的状态列中显示为待调查偶发情况

Comment

附加文本,例如关键词或对状态和严重性的说明。此值会填充结果列表窗格中的注释列。

附加文本在代码中可以跨多行。在报告中显示这些文本时,每行开头和结尾的空格会合并为一个空格,这样便可以将整个文本作为一个段落来阅读。

语法示例

隐藏单个缺陷

在缺陷所在行输入注解,并指定 Family (DEFECT) 和 Result_name (INT_OVFL)。当您未指定状态时,Polyspace 会指定状态为 No action planned,然后在后续分析中隐藏结果。

int var = INT_MAX;
var++; /* polyspace DEFECT : INT_OVFL */

隐藏单个编码标准违规

对编码标准违规进行申述,例如 CERT-C 违规。

在违规所在行输入注解,并指定 Family (CERT-C) 和 Result_name(规则编号,例如 STR31-C)。指定状态为 Justified,严重性为 Low,并添加注释。

line of code; /* polyspace CERT-C : STR31-C [Justified:Low] "Overflow cannot happen
                                            because of external constraints." */

隐藏多行上的所有 MISRA C:2012 违规

polyspaceFamily:Result_name 条目之间输入包含 +n 的注解。注解适用于所在行以及它后面的 n 行。

以下注解适用于第 4 行至第 7 行。行计数包括代码行、注释行以及空行。

4. line of code ; // polyspace +3 MISRA2012:* 
5. //comment
6. 
7. line of code;
8. line of code;

隐藏函数上的所有代码度量

要为函数级代码复杂度度量添加注解,请在函数定义中与函数名称相同的行上输入注解。

以下注解会隐藏 func 函数的所有代码复杂度度量:

char func(char param) { //polyspace CODE-METRICS:*
   ...
}

在同一条注解中指定多个族别

输入每个族别,族别之间用空格隔开。此注解适用于 MISRA C:2012 规则 17 的全部内容以及所有运行时检查。

line of code; /* polyspace MISRA2012 : 17.* RTE : * */

在同一条注解中指定多个结果名称

在您指定 Family (DEFECT) 后,输入每个 Result_name,名称之间用逗号分隔。

system("rm ~/.config"); /* polyspace DEFECT:UNSAFE_SYSTEM_CALL,RETURN_NOT_CHECKED */

隐藏显示全局变量使用情况的结果

要对显示全局变量使用情况(例如,未使用的全局变量)的 Code Prover 结果进行申述,请在变量声明旁边输入注解。

例如,要隐藏具有 Justified 状态、Low 严重性并附带一些注释的全局变量结果,您可以输入类似以下的注解:

int var; /* polyspace VARIABLE:* [Justified: Low] "Storage repo for later use"*/

为注解添加解释性注释

在指定 FamilyResult_name 后,您可以添加包含额外信息的 Comment 以用于申述。您可以为所有族别和结果名称提供一条注释,也可以为每个族别或结果名称分别提供注释。

  • 为所有结果提供相同注释:

    
    line of code; /* polyspace DEFECT : BAD_FREE MISRA2004:* "Comment for defect and MISRA" */
    

  • 为不同结果提供不同注释:

    
    line of code; /* polyspace DEFECT:* "Defect comment" polyspace MISRA2004:5.2 "MISRA comment" */
    
    在解析注解时,Polyspace 会忽略带双引号的文本之后的任何内容。在带双引号的文本之后输入 polyspace 关键字,以在同一代码行中为其他结果添加注解。

设置状态和严重性

您可以指定允许的值,或为状态和严重性输入自定义值。自定义严重性条目会被追加到状态中,并作为自定义状态存储在用户界面中。

//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] */

对代码块中的违规进行申述

使用注解对代码块引发的违规进行申述。以下列代码为例:

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 循环将硬编码字面值用作循环边界,这违反了 AUTOSAR C++14 Rule A5-1-1。通过使用 /*polyspace begin...*/ {...}/*polyspace-end...*/ 语法为代码块添加注解,第 for(int i = 0; i<10;++i){ 行的违规在结果列表中显示为已申述的缺陷。

已添加注解的代码块包含对 foo() 函数的调用。注解并不适用于此函数的函数体。例如,foo() 的返回语句中的违规会显示为未审查的缺陷。

对拼接行中的结果进行注解

对出现在拼接代码行中的结果进行注解。请参考以下代码:

#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);
}
拼接行中的运行时检查溢出 (Polyspace Code Prover)在后续审查中会被隐藏。

代码注解警告

如果您输入的代码注解有误,或者注解不再适用,分析日志将包含一条警告:

Warning: These Polyspace annotations do not apply to the current code
警告可能意味着以下情况之一:

  • 由于代码修复或分析配置更改,未再检测到该问题。

    例如,以下注解:

    /* polyspace RTE:IDP [No action planned:Low] */
    可能不再适用,因为之前显示为红色或橙色的非法解引用指针检查(注解为 IDP),现在显示为绿色。

  • 注解语法有误。

    polyspace 开头,后面跟一个单词,然后是一个 :(冒号)的注解,例如:

    // polyspace Family: 
    被视为用于对结果进行申述的 Polyspace 注解。如果 polyspace 后面的单词 Family 不是 Polyspace 结果类型(如 DEFECTRTE),分析会认为注解无效并显示警告。例如,此注解会触发警告:
    // polyspace TODO: Fix in March dev cycle
    因为 TODO 不是 Polyspace 结果类型。为了避免这些警告,请使用另一种分隔符,例如,不要使用冒号。有关结果类型的完整列表,请参阅代码注解语法

忽略代码注解

在某些情况下,您可能需要运行一次全新的分析,就好像结果之前从未被审查过一样。例如,您可能需要进行一次最坏情况分析,在此分析中,您会看到所有之前已申述的结果。

您可以使用 -ignore-code-annotations 选项来运行这种没有历史记录的分析。该分析会忽略代码注解,显示所有已进行注解的结果,而不从注解中获取任何审查信息。

另请参阅 -ignore-code-annotations

另请参阅

|

主题