#This script is designed to run with Understand - CodeCheck use base qw(Understand::Codecheck); use strict; use Codecheck::Libraries::InfoSiftr qw(resolveTypedefs); use constant ERR1 => 'Violation: union used for "%1".'; use constant ERR2 => 'Violation: union "%1" is invalid.'; sub register_tr_text { my $check = shift; $check->add_tr_text(ERR1); $check->add_tr_text(ERR2); } sub name { '9-5-1 Unions shall not be used' } sub description { '9-5-1 (Required) Unions shall not be used.' } sub detailed_description { <<'END_DESC'
Rationale
The use of unions to access an object in different ways may result in the data being misinterpreted.
Therefore, this rule prohibits the use of unions for any purpose.
It is recognized nonetheless that there are situations in which the careful use of unions is desirable in constructing an efficient implementation. In such situations, deviations to this rule are considered acceptable provided that all relevant implementation-defined behaviour is documented. This might be achieved in practice by referencing the implementation section of the compiler manuals from the design documentation.
Examplenamespace NS1 { // Compliant - no union } namespace NS2 { union U1 // Non-compliant – union { int32_t i; float32_t j; }; }END_DESC } sub test_language { my $language = shift; return $language eq 'C++'; } sub test_entity { 0 } sub test_global { 1 } sub define_options { } sub check { my $check = shift; my %typelist; foreach my $file ($check->get_files) { my $type; foreach my $ref ($file->filerefs('define, declare', 'union', 0)) { $check->violation($ref->ent, $ref->file, $ref->line, $ref->column, ERR2, $ref->ent->longname); } foreach my $ref ($file->filerefs('define, declare', 'object, typedef', 0)) { if($typelist{$ref->ent->type}){ $type = $typelist{$ref->ent->type}; } else{ $type = resolveTypedefs($ref->ent->type, $check->db); $typelist{$ref->ent->type} = $type; } next unless $type =~ m! \b union \b !x; $check->violation($ref->ent, $ref->file, $ref->line, $ref->column, ERR1, $ref->ent->longname); } } return; }