@@ -1662,9 +1662,18 @@ def identifier(nameToken):
16621662 internal_identifiers .append (i )
16631663 else :
16641664 names .append (var .nameToken .str )
1665- i = identifier (var .nameToken )
1666- i ['decl' ] = var .isExtern
1667- external_identifiers .append (i )
1665+ has_definition = False
1666+ for declaration in var .declarations or [var ]:
1667+ if declaration .isExtern and not getattr (declaration , 'isInit' , False ):
1668+ i = identifier (declaration .nameToken )
1669+ i ['decl' ] = True
1670+ external_identifiers .append (i )
1671+ else :
1672+ has_definition = True
1673+ if has_definition :
1674+ i = identifier (var .nameToken )
1675+ i ['decl' ] = False
1676+ external_identifiers .append (i )
16681677
16691678 for func in cfg .functions :
16701679 if func .tokenDef is None :
@@ -1690,21 +1699,31 @@ def _save_ctu_summary_usage(self, dumpfile, cfg):
16901699 return
16911700 self ._ctu_summary_usage = True
16921701
1693- names = []
1702+ declaration_tokens = {declaration .nameToken
1703+ for var in cfg .variables
1704+ for declaration in (var .declarations or [var ])}
1705+ names = set ()
1706+ usage = []
16941707 for token in cfg .tokenlist :
16951708 if not token .isName :
16961709 continue
16971710 if token .function and token != token .function .tokenDef :
1698- if ( not token .function .isStatic ) and ( token . str not in names ) :
1699- names . append ({ 'name' : token . str , 'file' : token . file })
1711+ if token .function .isStatic :
1712+ continue
17001713 elif token .variable :
1701- if token == token .variable .nameToken :
1714+ if token in declaration_tokens :
1715+ continue
1716+ if token .variable .access != 'Global' or token .variable .isStatic :
17021717 continue
1703- if token .variable .access == 'Global' and (not token .variable .isStatic ) and (token .str not in names ):
1704- names .append ({'name' : token .str , 'file' : token .file })
1718+ else :
1719+ continue
1720+ key = (token .str , token .file )
1721+ if key not in names :
1722+ names .add (key )
1723+ usage .append ({'name' : token .str , 'file' : token .file })
17051724
1706- if len (names ) > 0 :
1707- cppcheckdata .reportSummary (dumpfile , 'MisraUsage' , names )
1725+ if len (usage ) > 0 :
1726+ cppcheckdata .reportSummary (dumpfile , 'MisraUsage' , usage )
17081727
17091728
17101729 def misra_1_2 (self , cfg ):
@@ -2277,30 +2296,28 @@ def misra_8_4(self, cfg):
22772296 continue
22782297 if var .nameToken is None :
22792298 continue
2280- tok = var .nameToken
2281- if tok . next . str == ";" :
2282- if tok .next .isSplittedVarDeclEq :
2283- self .insert_in_dict (extern_var_with_def , tok .str , tok )
2299+ for declaration in var .declarations or [ var ]:
2300+ tok = declaration . nameToken
2301+ if tok .next .str == ";" and tok . next . isSplittedVarDeclEq :
2302+ self .insert_in_dict (extern_var_with_def , tok .str , declaration )
22842303 else :
2285- self .insert_in_dict (extern_var_without_def , tok .str , tok )
2286- else :
2287- self .insert_in_dict (extern_var_without_def , var .nameToken .str , var .nameToken )
2304+ self .insert_in_dict (extern_var_without_def , tok .str , declaration )
22882305
22892306 for var in extern_var_with_def :
22902307 if var not in extern_var_without_def :
22912308 for t in extern_var_with_def [var ]:
2292- self .reportError (t , 8 , 4 )
2309+ self .reportError (t . nameToken , 8 , 4 )
22932310
22942311 for var_str , var_tok in extern_var_without_def .items ():
22952312 warn = True
22962313 if var_str not in extern_var_with_def :
22972314 for t in var_tok :
2298- if t .variable . isExtern :
2315+ if t .isExtern :
22992316 warn = False
23002317 break
23012318 if warn :
23022319 for t in var_tok :
2303- self .reportError (t , 8 , 4 )
2320+ self .reportError (t . nameToken , 8 , 4 )
23042321
23052322 def misra_8_5 (self , dumpfile , cfg ):
23062323 self ._save_ctu_summary_identifiers (dumpfile , cfg )
@@ -2320,9 +2337,9 @@ def misra_8_8(self, cfg):
23202337 continue
23212338 varname = var .nameToken .str
23222339 if varname in vars :
2323- vars [varname ].append (var )
2340+ vars [varname ].extend (var . declarations or [ var ] )
23242341 else :
2325- vars [varname ] = [var ]
2342+ vars [varname ] = list ( var . declarations or [var ])
23262343 for varname , varlist in vars .items ():
23272344 static_var = None
23282345 extern_var = None
@@ -2363,8 +2380,9 @@ def misra_8_10(self, cfg):
23632380
23642381 def misra_8_11 (self , data ):
23652382 for var in data .variables :
2366- if var .isExtern and simpleMatch (var .nameToken .next , '[ ]' ) and var .nameToken .scope .type == 'Global' :
2367- self .reportError (var .nameToken , 8 , 11 )
2383+ for declaration in var .declarations or [var ]:
2384+ if declaration .isExtern and simpleMatch (declaration .nameToken .next , '[ ]' ) and declaration .nameToken .scope .type == 'Global' :
2385+ self .reportError (declaration .nameToken , 8 , 11 )
23682386
23692387 def misra_8_12 (self , data ):
23702388 for scope in data .scopes :
@@ -4908,84 +4926,85 @@ def is_different_file(loc1, loc2):
49084926
49094927 try :
49104928 for filename in ctu_info_files :
4911- for line in open (filename , 'rt' ):
4912- s = self .read_ctu_info_line (line )
4913- if s is None :
4914- continue
4915- summary_type = s .get ('summary' , '' )
4916- summary_data = s .get ('data' , None )
4917-
4918- if summary_type == 'MisraTypedefInfo' :
4919- for new_typedef_info in summary_data :
4920- key = new_typedef_info ['name' ]
4921- existing_typedef_info = all_typedef_info .get (key , None )
4922- if existing_typedef_info :
4923- if is_different_location (existing_typedef_info , new_typedef_info ):
4924- self .reportError (Location (existing_typedef_info ), 5 , 6 )
4925- self .reportError (Location (new_typedef_info ), 5 , 6 )
4929+ with open (filename , 'rt' ) as ctu_file :
4930+ for line in ctu_file :
4931+ s = self .read_ctu_info_line (line )
4932+ if s is None :
4933+ continue
4934+ summary_type = s .get ('summary' , '' )
4935+ summary_data = s .get ('data' , None )
4936+
4937+ if summary_type == 'MisraTypedefInfo' :
4938+ for new_typedef_info in summary_data :
4939+ key = new_typedef_info ['name' ]
4940+ existing_typedef_info = all_typedef_info .get (key , None )
4941+ if existing_typedef_info :
4942+ if is_different_location (existing_typedef_info , new_typedef_info ):
4943+ self .reportError (Location (existing_typedef_info ), 5 , 6 )
4944+ self .reportError (Location (new_typedef_info ), 5 , 6 )
4945+ else :
4946+ existing_typedef_info ['used' ] = existing_typedef_info ['used' ] or new_typedef_info ['used' ]
4947+ else :
4948+ all_typedef_info [key ] = new_typedef_info
4949+
4950+ if summary_type == 'MisraTagName' :
4951+ for new_tagname_info in summary_data :
4952+ key = new_tagname_info ['name' ]
4953+ existing_tagname_info = all_tagname_info .get (key , None )
4954+ if existing_tagname_info :
4955+ if is_different_location (existing_tagname_info , new_tagname_info ):
4956+ self .reportError (Location (existing_tagname_info ), 5 , 7 )
4957+ self .reportError (Location (new_tagname_info ), 5 , 7 )
4958+ else :
4959+ existing_tagname_info ['used' ] = existing_tagname_info ['used' ] or new_tagname_info ['used' ]
4960+ else :
4961+ all_tagname_info [key ] = new_tagname_info
4962+
4963+ if summary_type == 'MisraMacro' :
4964+ for new_macro in summary_data :
4965+ key = new_macro ['name' ]
4966+ existing_macro = all_macro_info .get (key , None )
4967+ if existing_macro :
4968+ existing_macro ['used' ] = existing_macro ['used' ] or new_macro ['used' ]
4969+ else :
4970+ all_macro_info [key ] = new_macro
4971+
4972+ if summary_type == 'MisraExternalIdentifiers' :
4973+ for s in sorted (summary_data , key = lambda d : "%s %s %s" % (d ['file' ],d ['line' ], d ['column' ] )):
4974+ is_declaration = s ['decl' ]
4975+ if is_declaration :
4976+ all_external_identifiers = all_external_identifiers_decl
49264977 else :
4927- existing_typedef_info ['used' ] = existing_typedef_info ['used' ] or new_typedef_info ['used' ]
4928- else :
4929- all_typedef_info [key ] = new_typedef_info
4930-
4931- if summary_type == 'MisraTagName' :
4932- for new_tagname_info in summary_data :
4933- key = new_tagname_info ['name' ]
4934- existing_tagname_info = all_tagname_info .get (key , None )
4935- if existing_tagname_info :
4936- if is_different_location (existing_tagname_info , new_tagname_info ):
4937- self .reportError (Location (existing_tagname_info ), 5 , 7 )
4938- self .reportError (Location (new_tagname_info ), 5 , 7 )
4978+ all_external_identifiers = all_external_identifiers_def
4979+
4980+ name = s ['name' ]
4981+ if name in all_external_identifiers :
4982+ if is_declaration and is_different_location (s , all_external_identifiers [name ]):
4983+ self .reportError (Location (s ), 8 , 5 )
4984+ self .reportError (Location (all_external_identifiers [name ]), 8 , 5 )
4985+ elif is_different_file (s , all_external_identifiers [name ]):
4986+ self .reportError (Location (s ), 8 , 6 )
4987+ self .reportError (Location (all_external_identifiers [name ]), 8 , 6 )
4988+ all_external_identifiers [name ] = s
4989+
4990+ if summary_type == 'MisraInternalIdentifiers' :
4991+ for s in summary_data :
4992+ if s ['name' ] in all_internal_identifiers :
4993+ if not s ['inlinefunc' ] or s ['file' ] != all_internal_identifiers [s ['name' ]]['file' ]:
4994+ self .reportError (Location (s ), 5 , 9 )
4995+ self .reportError (Location (all_internal_identifiers [s ['name' ]]), 5 , 9 )
4996+ all_internal_identifiers [s ['name' ]] = s
4997+
4998+ if summary_type == 'MisraLocalIdentifiers' :
4999+ for s in summary_data :
5000+ all_local_identifiers [s ['name' ]] = s
5001+
5002+ if summary_type == 'MisraUsage' :
5003+ for s in summary_data :
5004+ if s ['name' ] in all_usage_files :
5005+ all_usage_files [s ['name' ]].append (s ['file' ])
49395006 else :
4940- existing_tagname_info ['used' ] = existing_tagname_info ['used' ] or new_tagname_info ['used' ]
4941- else :
4942- all_tagname_info [key ] = new_tagname_info
4943-
4944- if summary_type == 'MisraMacro' :
4945- for new_macro in summary_data :
4946- key = new_macro ['name' ]
4947- existing_macro = all_macro_info .get (key , None )
4948- if existing_macro :
4949- existing_macro ['used' ] = existing_macro ['used' ] or new_macro ['used' ]
4950- else :
4951- all_macro_info [key ] = new_macro
4952-
4953- if summary_type == 'MisraExternalIdentifiers' :
4954- for s in sorted (summary_data , key = lambda d : "%s %s %s" % (d ['file' ],d ['line' ], d ['column' ] )):
4955- is_declaration = s ['decl' ]
4956- if is_declaration :
4957- all_external_identifiers = all_external_identifiers_decl
4958- else :
4959- all_external_identifiers = all_external_identifiers_def
4960-
4961- name = s ['name' ]
4962- if name in all_external_identifiers :
4963- if is_declaration and is_different_location (s , all_external_identifiers [name ]):
4964- self .reportError (Location (s ), 8 , 5 )
4965- self .reportError (Location (all_external_identifiers [name ]), 8 , 5 )
4966- elif is_different_file (s , all_external_identifiers [name ]):
4967- self .reportError (Location (s ), 8 , 6 )
4968- self .reportError (Location (all_external_identifiers [name ]), 8 , 6 )
4969- all_external_identifiers [name ] = s
4970-
4971- if summary_type == 'MisraInternalIdentifiers' :
4972- for s in summary_data :
4973- if s ['name' ] in all_internal_identifiers :
4974- if not s ['inlinefunc' ] or s ['file' ] != all_internal_identifiers [s ['name' ]]['file' ]:
4975- self .reportError (Location (s ), 5 , 9 )
4976- self .reportError (Location (all_internal_identifiers [s ['name' ]]), 5 , 9 )
4977- all_internal_identifiers [s ['name' ]] = s
4978-
4979- if summary_type == 'MisraLocalIdentifiers' :
4980- for s in summary_data :
4981- all_local_identifiers [s ['name' ]] = s
4982-
4983- if summary_type == 'MisraUsage' :
4984- for s in summary_data :
4985- if s ['name' ] in all_usage_files :
4986- all_usage_files [s ['name' ]].append (s ['file' ])
4987- else :
4988- all_usage_files [s ['name' ]] = [s ['file' ]]
5007+ all_usage_files [s ['name' ]] = [s ['file' ]]
49895008
49905009 except FileNotFoundError :
49915010 return
0 commit comments