Index: include/clang/StaticAnalyzer/Core/AnalyzerOptions.h =================================================================== --- include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -308,6 +308,9 @@ /// \sa shouldDisplayNotesAsEvents Optional DisplayNotesAsEvents; + /// \sa shouldDisplayMacroExpansions + Optional DisplayMacroExpansions; + /// \sa shouldAggressivelySimplifyBinaryOperation Optional AggressiveBinaryOperationSimplification; @@ -683,6 +686,13 @@ /// to false when unset. bool shouldDisplayNotesAsEvents(); + /// Returns true if macros related to the bugpath should be expanded and + /// included in the plist output. + /// + /// This is controlled by the 'expand-macros' option, which defaults to false + /// when unset. + bool shouldDisplayMacroExpansions(); + /// Returns true if SValBuilder should rearrange comparisons and additive /// operations of symbolic expressions which consist of a sum of a symbol and /// a concrete integer into the format where symbols are on the left-hand Index: lib/StaticAnalyzer/Core/AnalyzerOptions.cpp =================================================================== --- lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -463,6 +463,13 @@ return DisplayNotesAsEvents.getValue(); } +bool AnalyzerOptions::shouldDisplayMacroExpansions() { + if (!DisplayMacroExpansions.hasValue()) + DisplayMacroExpansions = + getBooleanOption("expand-macros", /*Default=*/false); + return DisplayMacroExpansions.getValue(); +} + bool AnalyzerOptions::shouldAggressivelySimplifyBinaryOperation() { if (!AggressiveBinaryOperationSimplification.hasValue()) AggressiveBinaryOperationSimplification = Index: lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- lib/StaticAnalyzer/Core/BugReporter.cpp +++ lib/StaticAnalyzer/Core/BugReporter.cpp @@ -546,7 +546,8 @@ } } -static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM); +static void CompactMacroExpandedPieces(PathPieces &path, + const SourceManager& SM); std::shared_ptr generateDiagForSwitchOP( @@ -1978,8 +1979,6 @@ PathDiagnosticLocation::createBegin(D, SM), CalleeLC); } - if (!AddPathEdges && GenerateDiagnostics) - CompactPathDiagnostic(PD->getMutablePieces(), SM); // Finally, prune the diagnostic path of uninteresting stuff. if (!PD->path.empty()) { @@ -2013,6 +2012,10 @@ removeRedundantMsgs(PD->getMutablePieces()); removeEdgesToDefaultInitializers(PD->getMutablePieces()); } + + if (GenerateDiagnostics && Opts.shouldDisplayMacroExpansions()) + CompactMacroExpandedPieces(PD->getMutablePieces(), SM); + return PD; } @@ -2442,9 +2445,10 @@ return true; } -/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object -/// and collapses PathDiagosticPieces that are expanded by macros. -static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) { +/// CompactMacroExpandedPieces - This function postprocesses a PathDiagnostic +/// object and collapses PathDiagosticPieces that are expanded by macros. +static void CompactMacroExpandedPieces(PathPieces &path, + const SourceManager& SM) { using MacroStackTy = std::vector< std::pair, SourceLocation>>; @@ -2460,7 +2464,7 @@ // Recursively compact calls. if (auto *call = dyn_cast(&*piece)) { - CompactPathDiagnostic(call->path, SM); + CompactMacroExpandedPieces(call->path, SM); } // Get the location of the PathDiagnosticPiece. Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp =================================================================== --- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -257,6 +257,20 @@ /*includeControlFlow*/ true); } +namespace { + +struct ExpansionInfo { + std::string MacroName; + std::string Expansion; + ExpansionInfo(std::string N, std::string E) + : MacroName(std::move(N)), Expansion(std::move(E)) {} +}; + +} // end of anonymous namespace + +static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc, + const Preprocessor &PP); + static void ReportMacro(raw_ostream &o, const PathDiagnosticMacroPiece& P, const FIDMap& FM, @@ -264,9 +278,44 @@ AnalyzerOptions &AnOpts, unsigned indent, unsigned depth) { + const SourceManager &SM = PP.getSourceManager(); - for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end(); - I!=E; ++I) { + llvm::SmallString<50> MacroMessage; + llvm::raw_svector_ostream MacroOS(MacroMessage); + + { + ExpansionInfo EI = getExpandedMacro(P.getLocation().asLocation(), PP); + + MacroOS << "Expanding macro '" << EI.MacroName << "' to '" + << EI.Expansion << '\''; + } + + Indent(o, indent) << "\n"; + ++indent; + + Indent(o, indent) << "kindmacro_expansion\n"; + + // Output the location. + FullSourceLoc L = P.getLocation().asLocation(); + + Indent(o, indent) << "location\n"; + EmitLocation(o, SM, L, FM, indent); + + // Output the ranges (if any). + ArrayRef Ranges = P.getRanges(); + EmitRanges(o, Ranges, FM, PP, indent); + + // Output the text. + EmitMessage(o, MacroOS.str(), indent); + + // Finish up. + --indent; + Indent(o, indent); + o << "\n"; + + for (PathPieces::const_iterator I = P.subPieces.begin(), + E = P.subPieces.end(); + I != E; ++I) { ReportPiece(o, **I, FM, PP, AnOpts, indent, depth, /*includeControlFlow*/ false); } @@ -617,3 +666,266 @@ // Finish. o << "\n"; } + +//===----------------------------------------------------------------------===// +// Helper functions and data structures for expanding macros. +//===----------------------------------------------------------------------===// + +namespace { + +using ExpArgTokens = llvm::SmallVector; + +/// Maps unexpanded macro arguments to expanded arguments. A macro argument may +/// need to expanded further when it is nested inside another macro. +class MacroArgMap : public std::map { +public: + void expandFromPrevMacro(const MacroArgMap &Super); +}; + +struct MacroNameAndArgs { + std::string Name; + const MacroInfo *MI = nullptr; + llvm::Optional Args; + + MacroNameAndArgs(std::string N, const MacroInfo *MI, + llvm::Optional M) + : Name(std::move(N)), MI(MI), Args(std::move(M)) {} +}; + +} // end of anonymous namespace + +/// Retrieves the name of the macro and what it's arguments expand into +/// at \p ExpanLoc. +/// +/// For example, for the following macro expansion: +/// +/// #define SET_TO_NULL(x) x = 0 +/// #define NOT_SUSPICIOUS(a) \ +/// { \ +/// int b = 0; \ +/// } \ +/// SET_TO_NULL(a) +/// +/// int *ptr = new int(4); +/// NOT_SUSPICIOUS(&ptr); +/// *ptr = 5; +/// +/// When \p ExpanLoc references the last line, the macro name "NOT_SUSPICIOUS" +/// and the MacroArgMap map { (a, &ptr) } will be returned. +/// +/// When \p ExpanLoc references "SET_TO_NULL(a)" within the definition of +/// "NOT_SUSPICOUS", the macro name "SET_TO_NULL" and the MacroArgMap map +/// { (x, a) } will be returned. +static MacroNameAndArgs getMacroNameAndArgs(SourceLocation ExpanLoc, + const Preprocessor &PP); + +static ExpansionInfo getExpandedMacroImpl(SourceLocation MacroLoc, + const Preprocessor &PP, + MacroArgMap *PrevArgs) { + + const SourceManager &SM = PP.getSourceManager(); + + MacroNameAndArgs Info = getMacroNameAndArgs(SM.getExpansionLoc(MacroLoc), PP); + + std::string MacroName = std::move(Info.Name); + const MacroInfo *MI = Info.MI; + llvm::Optional Args = std::move(Info.Args); + + // If this macro is function-like. + if (Args) { + // If this macro is nested inside another one, let's manually expand its + // arguments from the previous macro. + if (PrevArgs) + Args->expandFromPrevMacro(*PrevArgs); + PrevArgs = Args.getPointer(); + } else + PrevArgs = nullptr; + + // Iterate over the macro's tokens and stringify them. + llvm::SmallString<200> ExpansionBuf; + llvm::raw_svector_ostream ExpansionOS(ExpansionBuf); + + for (auto It = MI->tokens_begin(), E = MI->tokens_end(); It != E; ++It) { + Token T = *It; + + if (T.is(tok::identifier)) { + const auto *II = T.getIdentifierInfo(); + assert(II && + "This token is an identifier but has no IdentifierInfo!"); + + // If this token is a macro that should be expanded inside the currect + // macro. + if (const MacroInfo *MI = PP.getMacroInfo(II)) { + ExpansionOS << getExpandedMacroImpl(T.getLocation(), PP, PrevArgs) + .Expansion; + + // If this is a function-like macro, skip its arguments, as + // getExpandedMacro() already printed them. + if (MI->getNumParams() != 0) { + ++It; + assert(It->is(tok::l_paren) && + "This token should be '(' if the previous was a function-like " + "macro!"); + + // Skip until we find the closing ')'. + int ParanthesesDepth = 1; + while (ParanthesesDepth != 0) { + ++It; + + assert(It->isNot(tok::eof) && + "Encountered EOF while attempting to skip macro arguments!"); + assert(It != E && + "End of the macro definition reached before finding ')'!"); + + if (It->is(tok::l_paren)) + ++ParanthesesDepth; + + if (It->is(tok::r_paren)) + --ParanthesesDepth; + } + } + continue; + } + + // If this token is the current macro's argument, we should expand it. + if (Args && Args->count(II)) { + for (const Token &ExpandedArgT : Args->at(II)) { + ExpansionOS << PP.getSpelling(ExpandedArgT) + ' '; + } + continue; + } + } + + // TODO: Handle tok::hash and tok::hashhash. + + // If control reaches here, there's nothing left to do, print the token. + ExpansionOS << PP.getSpelling(T) + ' '; + } + + return {MacroName, ExpansionOS.str()}; +} + +static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc, + const Preprocessor &PP) { + return getExpandedMacroImpl(MacroLoc, PP, /* PrevArgs */ nullptr); +} + +static MacroNameAndArgs getMacroNameAndArgs(SourceLocation ExpanLoc, + const Preprocessor &PP) { + + const SourceManager &SM = PP.getSourceManager(); + const LangOptions &LangOpts = PP.getLangOpts(); + + // First, we create a Lexer to lex *at the expansion location* the tokens + // referring to the macro's name and its arguments. + std::pair LocInfo = SM.getDecomposedLoc(ExpanLoc); + const llvm::MemoryBuffer *MB = SM.getBuffer(LocInfo.first); + const char *MacroNameTokenPos = MB->getBufferStart() + LocInfo.second; + + Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts, + MB->getBufferStart(), MacroNameTokenPos, MB->getBufferEnd()); + + // Acquire the macro's name. + Token TheTok; + RawLexer.LexFromRawLexer(TheTok); + + std::string MacroName = PP.getSpelling(TheTok); + + // Acquire the macro's arguments. + // + // The rough idea here is to lex from the first left parantheses to the last + // right parantheses, and map the macro's unexpanded arguments to what they + // will be expanded to. An expanded macro argument may contain several tokens + // (like '3 + 4'), so we'll lex until we find a tok::comma or tok::r_paren, at + // which point we start lexing the next argument or finish. + const auto *II = PP.getIdentifierInfo(MacroName); + assert(II && "Failed to acquire the IndetifierInfo for the macro!"); + const MacroInfo *MI = PP.getMacroInfo(II); + assert(MI && "This IdentifierInfo should refer to a macro!"); + + ArrayRef MacroArgs = MI->params(); + if (MacroArgs.empty()) + return { MacroName, MI, None }; + + RawLexer.LexFromRawLexer(TheTok); + assert(TheTok.is(tok::l_paren) && + "The token after the macro's identifier token should be '('!"); + + MacroArgMap Args; + + // When the macro's argument is a function call, like + // CALL_FN(someFunctionName(param1, param2)) + // we will find tok::l_paren, tok::r_paren, and tok::comma that do not divide + // actual macro arguments, or do not represent the macro argument's closing + // parantheses, so we'll count how many parantheses aren't closed yet. + int ParanthesesDepth = 1; + + for (unsigned Index = 0; Index < MI->getNumParams(); ++Index) { + MacroArgMap::mapped_type ExpandedArgTokens; + + // Lex the first token of the next macro parameter. + RawLexer.LexFromRawLexer(TheTok); + + while (TheTok.isNot(tok::comma) || ParanthesesDepth != 1) { + assert(TheTok.isNot(tok::eof) && + "EOF encountered while looking for expanded macro args!"); + + if (TheTok.is(tok::l_paren)) + ++ParanthesesDepth; + + if (TheTok.is(tok::r_paren)) + --ParanthesesDepth; + + if (ParanthesesDepth == 0) + break; + + if (TheTok.is(tok::raw_identifier)) + PP.LookUpIdentifierInfo(TheTok); + + ExpandedArgTokens.push_back(TheTok); + RawLexer.LexFromRawLexer(TheTok); + } + + Args.insert(std::make_pair(MacroArgs[Index], ExpandedArgTokens)); + } + + // TODO: The condition really should be TheTok.is(tok::r_paren), but variadic + // macro arguments are not handled yet. + assert(TheTok.isOneOf(tok::r_paren, tok::comma) && + "Expanded macro argument acquisition failed! After the end of the loop" + " this token should be ')'!"); + + return { MacroName, MI, Args }; +} + +void MacroArgMap::expandFromPrevMacro(const MacroArgMap &Super) { + + for (value_type &Pair : *this) { + ExpArgTokens &CurrExpArgTokens = Pair.second; + + // For each token in the expanded macro argument. + auto It = CurrExpArgTokens.begin(); + while (It != CurrExpArgTokens.end()) { + if (It->isNot(tok::identifier)) { + ++It; + continue; + } + + const auto *II = It->getIdentifierInfo(); + assert(II); + + // Is this an argument that "Super" expands further? + if (!Super.count(II)) { + ++It; + continue; + } + + const ExpArgTokens &SuperExpArgTokens = Super.at(II); + + It = CurrExpArgTokens.insert( + It, SuperExpArgTokens.begin(), SuperExpArgTokens.end()); + std::advance(It, SuperExpArgTokens.size()); + It = CurrExpArgTokens.erase(It); + } + } +} Index: test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist =================================================================== --- /dev/null +++ test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist @@ -0,0 +1,4094 @@ + + + + + clang_version +clang version 8.0.0 (http://mainstream.inf.elte.hu/Szelethus/clang 6c803b6a046d17b823017f92c987e34702253b6d) (https://github.com/llvm-mirror/llvm 1ffbf26a1a0a190d69327af875a3337b74a2ce82) + diagnostics + + + path + + + kindcontrol + edges + + + start + + + line25 + col3 + file0 + + + line25 + col5 + file0 + + + end + + + line26 + col3 + file0 + + + line26 + col21 + file0 + + + + + + + kindmacro_expansion + location + + line26 + col3 + file0 + + extended_message + Expanding macro 'SET_PTR_VAR_TO_NULL' to 'ptr = 0 ' + message + Expanding macro 'SET_PTR_VAR_TO_NULL' to 'ptr = 0 ' + + + kindevent + location + + line26 + col3 + file0 + + ranges + + + + line26 + col3 + file0 + + + line26 + col21 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line27 + col3 + file0 + + + line27 + col3 + file0 + + + end + + + line27 + col8 + file0 + + + line27 + col8 + file0 + + + + + + + kindevent + location + + line27 + col8 + file0 + + ranges + + + + line27 + col4 + file0 + + + line27 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextf8fbc46cc5afbb056d92bd3d3d702781 + issue_context_kindfunction + issue_contextnonFunctionLikeMacroTest + issue_hash_function_offset3 + location + + line27 + col8 + file0 + + ExecutedLines + + 0 + + 24 + 25 + 26 + 27 + + + + + path + + + kindcontrol + edges + + + start + + + line37 + col3 + file0 + + + line37 + col5 + file0 + + + end + + + line38 + col3 + file0 + + + line38 + col39 + file0 + + + + + + + kindmacro_expansion + location + + line38 + col3 + file0 + + extended_message + Expanding macro 'SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO' to 'ptr = 0 ' + message + Expanding macro 'SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO' to 'ptr = 0 ' + + + kindevent + location + + line38 + col3 + file0 + + ranges + + + + line38 + col3 + file0 + + + line38 + col39 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line39 + col3 + file0 + + + line39 + col3 + file0 + + + end + + + line39 + col8 + file0 + + + line39 + col8 + file0 + + + + + + + kindevent + location + + line39 + col8 + file0 + + ranges + + + + line39 + col4 + file0 + + + line39 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextd5eba61193b41c27fc7b2705cbd607ba + issue_context_kindfunction + issue_contextnonFunctionLikeNestedMacroTest + issue_hash_function_offset3 + location + + line39 + col8 + file0 + + ExecutedLines + + 0 + + 36 + 37 + 38 + 39 + + + + + path + + + kindcontrol + edges + + + start + + + line56 + col3 + file0 + + + line56 + col5 + file0 + + + end + + + line57 + col3 + file0 + + + line57 + col9 + file0 + + + + + + + kindmacro_expansion + location + + line57 + col3 + file0 + + extended_message + Expanding macro 'TO_NULL' to 'setToNull ( & ptr) ' + message + Expanding macro 'TO_NULL' to 'setToNull ( & ptr) ' + + + kindevent + location + + line57 + col3 + file0 + + ranges + + + + line57 + col3 + file0 + + + line57 + col15 + file0 + + + + depth0 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth1 + extended_message + Entered call from 'functionLikeMacroTest' + message + Entered call from 'functionLikeMacroTest' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth1 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindevent + location + + line57 + col3 + file0 + + ranges + + + + line57 + col3 + file0 + + + line57 + col15 + file0 + + + + depth0 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindcontrol + edges + + + start + + + line58 + col3 + file0 + + + line58 + col3 + file0 + + + end + + + line58 + col8 + file0 + + + line58 + col8 + file0 + + + + + + + kindevent + location + + line58 + col8 + file0 + + ranges + + + + line58 + col4 + file0 + + + line58 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context370a457744311752aac789447b4ef16c + issue_context_kindfunction + issue_contextfunctionLikeMacroTest + issue_hash_function_offset3 + location + + line58 + col8 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 55 + 56 + 57 + 58 + + + + + path + + + kindcontrol + edges + + + start + + + line75 + col3 + file0 + + + line75 + col5 + file0 + + + end + + + line76 + col3 + file0 + + + line76 + col9 + file0 + + + + + + + kindmacro_expansion + location + + line76 + col3 + file0 + + extended_message + Expanding macro 'TO_NULL' to 'setToNull ( & a) ' + message + Expanding macro 'TO_NULL' to 'setToNull ( & a) ' + + + kindevent + location + + line76 + col3 + file0 + + ranges + + + + line76 + col3 + file0 + + + line76 + col13 + file0 + + + + depth0 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth1 + extended_message + Entered call from 'functionLikeNestedMacroTest' + message + Entered call from 'functionLikeNestedMacroTest' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth1 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindevent + location + + line76 + col3 + file0 + + ranges + + + + line76 + col3 + file0 + + + line76 + col13 + file0 + + + + depth0 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindmacro_expansion + location + + line77 + col3 + file0 + + extended_message + Expanding macro 'DEREF' to '{ int b ; b = 5 ; } print ( a) ; * a' + message + Expanding macro 'DEREF' to '{ int b ; b = 5 ; } print ( a) ; * a' + + + kindevent + location + + line77 + col12 + file0 + + ranges + + + + line77 + col3 + file0 + + + line77 + col10 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context873802674657bba4565f64c7bbf0ded9 + issue_context_kindfunction + issue_contextfunctionLikeNestedMacroTest + issue_hash_function_offset3 + location + + line77 + col12 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 74 + 75 + 76 + 77 + + + + + path + + + kindcontrol + edges + + + start + + + line100 + col3 + file0 + + + line100 + col5 + file0 + + + end + + + line101 + col3 + file0 + + + line101 + col19 + file0 + + + + + + + kindmacro_expansion + location + + line101 + col3 + file0 + + extended_message + Expanding macro 'TO_NULL_AND_PRINT' to ' a= 0 ; print ( "Will this , cause a crash?") ' + message + Expanding macro 'TO_NULL_AND_PRINT' to ' a= 0 ; print ( "Will this , cause a crash?") ' + + + kindevent + location + + line101 + col3 + file0 + + ranges + + + + line101 + col3 + file0 + + + line101 + col52 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindcontrol + edges + + + start + + + line102 + col3 + file0 + + + line102 + col3 + file0 + + + end + + + line102 + col6 + file0 + + + line102 + col6 + file0 + + + + + + + kindevent + location + + line102 + col6 + file0 + + ranges + + + + line102 + col4 + file0 + + + line102 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context7a7344244350405a514682fe228e304e + issue_context_kindfunction + issue_contextmacroArgContainsCommaInStringTest + issue_hash_function_offset3 + location + + line102 + col6 + file0 + + ExecutedLines + + 0 + + 99 + 100 + 101 + 102 + + + + + path + + + kindcontrol + edges + + + start + + + line108 + col3 + file0 + + + line108 + col5 + file0 + + + end + + + line109 + col3 + file0 + + + line109 + col19 + file0 + + + + + + + kindmacro_expansion + location + + line109 + col3 + file0 + + extended_message + Expanding macro 'TO_NULL_AND_PRINT' to ' a= 0 ; print ( "Will this ( cause a crash?") ' + message + Expanding macro 'TO_NULL_AND_PRINT' to ' a= 0 ; print ( "Will this ( cause a crash?") ' + + + kindevent + location + + line109 + col3 + file0 + + ranges + + + + line109 + col3 + file0 + + + line109 + col52 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindcontrol + edges + + + start + + + line110 + col3 + file0 + + + line110 + col3 + file0 + + + end + + + line110 + col6 + file0 + + + line110 + col6 + file0 + + + + + + + kindevent + location + + line110 + col6 + file0 + + ranges + + + + line110 + col4 + file0 + + + line110 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context1d6d14e3f566cec02bd1f3542e3c8044 + issue_context_kindfunction + issue_contextmacroArgContainsLParenInStringTest + issue_hash_function_offset3 + location + + line110 + col6 + file0 + + ExecutedLines + + 0 + + 107 + 108 + 109 + 110 + + + + + path + + + kindcontrol + edges + + + start + + + line116 + col3 + file0 + + + line116 + col5 + file0 + + + end + + + line117 + col3 + file0 + + + line117 + col19 + file0 + + + + + + + kindmacro_expansion + location + + line117 + col3 + file0 + + extended_message + Expanding macro 'TO_NULL_AND_PRINT' to ' a= 0 ; print ( "Will this ) cause a crash?") ' + message + Expanding macro 'TO_NULL_AND_PRINT' to ' a= 0 ; print ( "Will this ) cause a crash?") ' + + + kindevent + location + + line117 + col3 + file0 + + ranges + + + + line117 + col3 + file0 + + + line117 + col52 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindcontrol + edges + + + start + + + line118 + col3 + file0 + + + line118 + col3 + file0 + + + end + + + line118 + col6 + file0 + + + line118 + col6 + file0 + + + + + + + kindevent + location + + line118 + col6 + file0 + + ranges + + + + line118 + col4 + file0 + + + line118 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context7354d762d71f0d0a3ffc9d6d827fe580 + issue_context_kindfunction + issue_contextmacroArgContainsRParenInStringTest + issue_hash_function_offset3 + location + + line118 + col6 + file0 + + ExecutedLines + + 0 + + 115 + 116 + 117 + 118 + + + + + path + + + kindcontrol + edges + + + start + + + line129 + col3 + file0 + + + line129 + col5 + file0 + + + end + + + line130 + col3 + file0 + + + line130 + col15 + file0 + + + + + + + kindmacro_expansion + location + + line130 + col3 + file0 + + extended_message + Expanding macro 'CALL_FUNCTION' to ' setToNull ( & a )' + message + Expanding macro 'CALL_FUNCTION' to ' setToNull ( & a )' + + + kindevent + location + + line130 + col3 + file0 + + ranges + + + + line130 + col3 + file0 + + + line130 + col30 + file0 + + + + depth0 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth1 + extended_message + Entered call from 'macroArgContainsLParenRParenTest' + message + Entered call from 'macroArgContainsLParenRParenTest' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth1 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindevent + location + + line130 + col3 + file0 + + ranges + + + + line130 + col3 + file0 + + + line130 + col30 + file0 + + + + depth0 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindcontrol + edges + + + start + + + line131 + col3 + file0 + + + line131 + col3 + file0 + + + end + + + line131 + col6 + file0 + + + line131 + col6 + file0 + + + + + + + kindevent + location + + line131 + col6 + file0 + + ranges + + + + line131 + col4 + file0 + + + line131 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextf00b6f77288a374e864a58609e9a42ea + issue_context_kindfunction + issue_contextmacroArgContainsLParenRParenTest + issue_hash_function_offset3 + location + + line131 + col6 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 128 + 129 + 130 + 131 + + + + + path + + + kindcontrol + edges + + + start + + + line142 + col3 + file0 + + + line142 + col5 + file0 + + + end + + + line143 + col3 + file0 + + + line143 + col15 + file0 + + + + + + + kindmacro_expansion + location + + line143 + col3 + file0 + + extended_message + Expanding macro 'CALL_FUNCTION' to ' setToNullAndPrint ( & a , "Hello!" )' + message + Expanding macro 'CALL_FUNCTION' to ' setToNullAndPrint ( & a , "Hello!" )' + + + kindevent + location + + line143 + col3 + file0 + + ranges + + + + line143 + col3 + file0 + + + line143 + col48 + file0 + + + + depth0 + extended_message + Calling 'setToNullAndPrint' + message + Calling 'setToNullAndPrint' + + + kindevent + location + + line136 + col1 + file0 + + depth1 + extended_message + Entered call from 'macroArgContainsCommaLParenRParenTest' + message + Entered call from 'macroArgContainsCommaLParenRParenTest' + + + kindcontrol + edges + + + start + + + line136 + col1 + file0 + + + line136 + col4 + file0 + + + end + + + line137 + col3 + file0 + + + line137 + col11 + file0 + + + + + + + kindevent + location + + line137 + col3 + file0 + + ranges + + + + line137 + col3 + file0 + + + line137 + col17 + file0 + + + + depth1 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth2 + extended_message + Entered call from 'setToNullAndPrint' + message + Entered call from 'setToNullAndPrint' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth2 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindevent + location + + line137 + col3 + file0 + + ranges + + + + line137 + col3 + file0 + + + line137 + col17 + file0 + + + + depth1 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindcontrol + edges + + + start + + + line137 + col3 + file0 + + + line137 + col11 + file0 + + + end + + + line138 + col3 + file0 + + + line138 + col7 + file0 + + + + + + + kindevent + location + + line143 + col3 + file0 + + ranges + + + + line143 + col3 + file0 + + + line143 + col48 + file0 + + + + depth0 + extended_message + Returning from 'setToNullAndPrint' + message + Returning from 'setToNullAndPrint' + + + kindcontrol + edges + + + start + + + line144 + col3 + file0 + + + line144 + col3 + file0 + + + end + + + line144 + col6 + file0 + + + line144 + col6 + file0 + + + + + + + kindevent + location + + line144 + col6 + file0 + + ranges + + + + line144 + col4 + file0 + + + line144 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextc5805abeb71bb4edb41b49ab317439b9 + issue_context_kindfunction + issue_contextmacroArgContainsCommaLParenRParenTest + issue_hash_function_offset3 + location + + line144 + col6 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 136 + 137 + 138 + 141 + 142 + 143 + 144 + + + + + path + + + kindcontrol + edges + + + start + + + line153 + col3 + file0 + + + line153 + col5 + file0 + + + end + + + line154 + col3 + file0 + + + line154 + col31 + file0 + + + + + + + kindmacro_expansion + location + + line154 + col3 + file0 + + extended_message + Expanding macro 'CALL_FUNCTION_WITH_TWO_PARAMS' to ' setToNullAndPrint( & a, "Hello!") ' + message + Expanding macro 'CALL_FUNCTION_WITH_TWO_PARAMS' to ' setToNullAndPrint( & a, "Hello!") ' + + + kindevent + location + + line154 + col3 + file0 + + ranges + + + + line154 + col3 + file0 + + + line154 + col64 + file0 + + + + depth0 + extended_message + Calling 'setToNullAndPrint' + message + Calling 'setToNullAndPrint' + + + kindevent + location + + line136 + col1 + file0 + + depth1 + extended_message + Entered call from 'macroArgContainsCommaLParenRParenTest2' + message + Entered call from 'macroArgContainsCommaLParenRParenTest2' + + + kindcontrol + edges + + + start + + + line136 + col1 + file0 + + + line136 + col4 + file0 + + + end + + + line137 + col3 + file0 + + + line137 + col11 + file0 + + + + + + + kindevent + location + + line137 + col3 + file0 + + ranges + + + + line137 + col3 + file0 + + + line137 + col17 + file0 + + + + depth1 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth2 + extended_message + Entered call from 'setToNullAndPrint' + message + Entered call from 'setToNullAndPrint' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth2 + extended_message + Null pointer value stored to 'a' + message + Null pointer value stored to 'a' + + + kindevent + location + + line137 + col3 + file0 + + ranges + + + + line137 + col3 + file0 + + + line137 + col17 + file0 + + + + depth1 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindcontrol + edges + + + start + + + line137 + col3 + file0 + + + line137 + col11 + file0 + + + end + + + line138 + col3 + file0 + + + line138 + col7 + file0 + + + + + + + kindevent + location + + line154 + col3 + file0 + + ranges + + + + line154 + col3 + file0 + + + line154 + col64 + file0 + + + + depth0 + extended_message + Returning from 'setToNullAndPrint' + message + Returning from 'setToNullAndPrint' + + + kindcontrol + edges + + + start + + + line155 + col3 + file0 + + + line155 + col3 + file0 + + + end + + + line155 + col6 + file0 + + + line155 + col6 + file0 + + + + + + + kindevent + location + + line155 + col6 + file0 + + ranges + + + + line155 + col4 + file0 + + + line155 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'a') + message + Dereference of null pointer (loaded from variable 'a') + + + descriptionDereference of null pointer (loaded from variable 'a') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context4014a22ef054933e6ce9be43623ea85e + issue_context_kindfunction + issue_contextmacroArgContainsCommaLParenRParenTest2 + issue_hash_function_offset3 + location + + line155 + col6 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 136 + 137 + 138 + 152 + 153 + 154 + 155 + + + + + path + + + kindcontrol + edges + + + start + + + line164 + col3 + file0 + + + line164 + col5 + file0 + + + end + + + line168 + col3 + file0 + + + line168 + col13 + file0 + + + + + + + kindmacro_expansion + location + + line168 + col3 + file0 + + extended_message + Expanding macro 'CALL_LAMBDA' to ' ( [ & ptr , str ] ( ) mutable { TO_NULL ( & ptr ) ; } )( ) ' + message + Expanding macro 'CALL_LAMBDA' to ' ( [ & ptr , str ] ( ) mutable { TO_NULL ( & ptr ) ; } )( ) ' + + + kindevent + location + + line168 + col3 + file0 + + ranges + + + + line168 + col3 + file0 + + + line168 + col58 + file0 + + + + depth0 + extended_message + Calling 'operator()' + message + Calling 'operator()' + + + kindevent + location + + line168 + col3 + file0 + + depth1 + extended_message + Entered call from 'commaInBracketsTest' + message + Entered call from 'commaInBracketsTest' + + + kindmacro_expansion + location + + line168 + col3 + file0 + + extended_message + Expanding macro 'CALL_LAMBDA' to ' ( [ & ptr , str ] ( ) mutable { TO_NULL ( & ptr ) ; } )( ) ' + message + Expanding macro 'CALL_LAMBDA' to ' ( [ & ptr , str ] ( ) mutable { TO_NULL ( & ptr ) ; } )( ) ' + + + kindevent + location + + line168 + col3 + file0 + + ranges + + + + line168 + col3 + file0 + + + line168 + col58 + file0 + + + + depth1 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth2 + extended_message + Entered call from 'operator()' + message + Entered call from 'operator()' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth2 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindevent + location + + line168 + col3 + file0 + + ranges + + + + line168 + col3 + file0 + + + line168 + col58 + file0 + + + + depth1 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindevent + location + + line168 + col3 + file0 + + ranges + + + + line168 + col3 + file0 + + + line168 + col58 + file0 + + + + depth0 + extended_message + Returning from 'operator()' + message + Returning from 'operator()' + + + kindcontrol + edges + + + start + + + line169 + col3 + file0 + + + line169 + col3 + file0 + + + end + + + line169 + col8 + file0 + + + line169 + col8 + file0 + + + + + + + kindevent + location + + line169 + col8 + file0 + + ranges + + + + line169 + col4 + file0 + + + line169 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contexta8918c38ddfa6a991701e7d19c9cd6bb + issue_context_kindfunction + issue_contextcommaInBracketsTest + issue_hash_function_offset6 + location + + line169 + col8 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 163 + 164 + 165 + 168 + 169 + + + + + path + + + kindmacro_expansion + location + + line178 + col3 + file0 + + extended_message + Expanding macro 'PASTE_CODE' to ' { int * ptr = nullptr ; * ptr = 5 ; }' + message + Expanding macro 'PASTE_CODE' to ' { int * ptr = nullptr ; * ptr = 5 ; }' + + + kindevent + location + + line178 + col3 + file0 + + ranges + + + + line178 + col3 + file0 + + + line186 + col4 + file0 + + + + depth0 + extended_message + 'ptr' initialized to a null pointer value + message + 'ptr' initialized to a null pointer value + + + kindevent + location + + line178 + col3 + file0 + + ranges + + + + line178 + col3 + file0 + + + line186 + col4 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context63042e03ae0d2f3832b141a63b1d4d49 + issue_context_kindfunction + issue_contextcommaInBracesTest + issue_hash_function_offset1 + location + + line178 + col3 + file0 + + ExecutedLines + + 0 + + 177 + 178 + + + + + path + + + kindcontrol + edges + + + start + + + line199 + col3 + file0 + + + line199 + col5 + file0 + + + end + + + line201 + col3 + file0 + + + line201 + col25 + file0 + + + + + + + kindmacro_expansion + location + + line201 + col3 + file0 + + extended_message + Expanding macro 'POTENTIALLY_EMPTY_PARAM' to '; ptr= nullptr ' + message + Expanding macro 'POTENTIALLY_EMPTY_PARAM' to '; ptr= nullptr ' + + + kindevent + location + + line201 + col3 + file0 + + ranges + + + + line201 + col3 + file0 + + + line201 + col31 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line202 + col3 + file0 + + + line202 + col3 + file0 + + + end + + + line202 + col8 + file0 + + + line202 + col8 + file0 + + + + + + + kindevent + location + + line202 + col8 + file0 + + ranges + + + + line202 + col4 + file0 + + + line202 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextcd980e278fbcd8f77bbeac79285084e2 + issue_context_kindfunction + issue_contextemptyParamTest + issue_hash_function_offset4 + location + + line202 + col8 + file0 + + ExecutedLines + + 0 + + 198 + 199 + 201 + 202 + + + + + path + + + kindcontrol + edges + + + start + + + line212 + col3 + file0 + + + line212 + col5 + file0 + + + end + + + line214 + col3 + file0 + + + line214 + col20 + file0 + + + + + + + kindmacro_expansion + location + + line214 + col3 + file0 + + extended_message + Expanding macro 'NESTED_EMPTY_PARAM' to '; ptr= nullptr ; ' + message + Expanding macro 'NESTED_EMPTY_PARAM' to '; ptr= nullptr ; ' + + + kindevent + location + + line214 + col3 + file0 + + ranges + + + + line214 + col3 + file0 + + + line214 + col27 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line215 + col3 + file0 + + + line215 + col3 + file0 + + + end + + + line215 + col8 + file0 + + + line215 + col8 + file0 + + + + + + + kindevent + location + + line215 + col8 + file0 + + ranges + + + + line215 + col4 + file0 + + + line215 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextf6a5f6c93b6e3734842ddabd3d5a7341 + issue_context_kindfunction + issue_contextnestedEmptyParamTest + issue_hash_function_offset4 + location + + line215 + col8 + file0 + + ExecutedLines + + 0 + + 211 + 212 + 214 + 215 + + + + + path + + + kindcontrol + edges + + + start + + + line224 + col3 + file0 + + + line224 + col5 + file0 + + + end + + + line225 + col3 + file0 + + + line225 + col44 + file0 + + + + + + + kindmacro_expansion + location + + line225 + col3 + file0 + + extended_message + Expanding macro 'CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO' to ' setToNull ( & ptr )' + message + Expanding macro 'CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO' to ' setToNull ( & ptr )' + + + kindevent + location + + line225 + col3 + file0 + + ranges + + + + line225 + col3 + file0 + + + line225 + col61 + file0 + + + + depth0 + extended_message + Calling 'setToNull' + message + Calling 'setToNull' + + + kindevent + location + + line48 + col1 + file0 + + depth1 + extended_message + Entered call from 'lParenRParenInNestedMacro' + message + Entered call from 'lParenRParenInNestedMacro' + + + kindcontrol + edges + + + start + + + line48 + col1 + file0 + + + line48 + col4 + file0 + + + end + + + line49 + col3 + file0 + + + line49 + col3 + file0 + + + + + + + kindevent + location + + line49 + col3 + file0 + + ranges + + + + line49 + col3 + file0 + + + line49 + col17 + file0 + + + + depth1 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindevent + location + + line225 + col3 + file0 + + ranges + + + + line225 + col3 + file0 + + + line225 + col61 + file0 + + + + depth0 + extended_message + Returning from 'setToNull' + message + Returning from 'setToNull' + + + kindcontrol + edges + + + start + + + line226 + col3 + file0 + + + line226 + col3 + file0 + + + end + + + line226 + col8 + file0 + + + line226 + col8 + file0 + + + + + + + kindevent + location + + line226 + col8 + file0 + + ranges + + + + line226 + col4 + file0 + + + line226 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contextff00c8344e685317303e814970082d5f + issue_context_kindfunction + issue_contextlParenRParenInNestedMacro + issue_hash_function_offset3 + location + + line226 + col8 + file0 + + ExecutedLines + + 0 + + 48 + 49 + 223 + 224 + 225 + 226 + + + + + path + + + kindcontrol + edges + + + start + + + line243 + col3 + file0 + + + line243 + col5 + file0 + + + end + + + line244 + col3 + file0 + + + line244 + col22 + file0 + + + + + + + kindmacro_expansion + location + + line244 + col3 + file0 + + extended_message + Expanding macro 'VARIADIC_SET_TO_NULL' to ' ptr= nullptr ; variadicFunc ( 1) ' + message + Expanding macro 'VARIADIC_SET_TO_NULL' to ' ptr= nullptr ; variadicFunc ( 1) ' + + + kindevent + location + + line244 + col3 + file0 + + ranges + + + + line244 + col3 + file0 + + + line244 + col42 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line245 + col3 + file0 + + + line245 + col3 + file0 + + + end + + + line245 + col8 + file0 + + + line245 + col8 + file0 + + + + + + + kindevent + location + + line245 + col8 + file0 + + ranges + + + + line245 + col4 + file0 + + + line245 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context1b0880549df23e9ce0edb60955ad5ac1 + issue_context_kindfunction + issue_contextvariadicMacroArgumentTest + issue_hash_function_offset3 + location + + line245 + col8 + file0 + + ExecutedLines + + 0 + + 242 + 243 + 244 + 245 + + + + + path + + + kindcontrol + edges + + + start + + + line260 + col3 + file0 + + + line260 + col5 + file0 + + + end + + + line261 + col3 + file0 + + + line261 + col30 + file0 + + + + + + + kindmacro_expansion + location + + line261 + col3 + file0 + + extended_message + Expanding macro 'DECLARE_FUNC_AND_SET_TO_NULL' to 'void generated_ ## whatever( ) ; ptr= nullptr ; ' + message + Expanding macro 'DECLARE_FUNC_AND_SET_TO_NULL' to 'void generated_ ## whatever( ) ; ptr= nullptr ; ' + + + kindevent + location + + line261 + col3 + file0 + + ranges + + + + line261 + col3 + file0 + + + line261 + col45 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line262 + col3 + file0 + + + line262 + col3 + file0 + + + end + + + line262 + col8 + file0 + + + line262 + col8 + file0 + + + + + + + kindevent + location + + line262 + col8 + file0 + + ranges + + + + line262 + col4 + file0 + + + line262 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context453ed8096f5394e74e16f965886e5623 + issue_context_kindfunction + issue_contexthashHashOperatorTest + issue_hash_function_offset3 + location + + line262 + col8 + file0 + + ExecutedLines + + 0 + + 259 + 260 + 261 + 262 + + + + + path + + + kindcontrol + edges + + + start + + + line273 + col3 + file0 + + + line273 + col5 + file0 + + + end + + + line274 + col3 + file0 + + + line274 + col11 + file0 + + + + + + + kindmacro_expansion + location + + line274 + col3 + file0 + + extended_message + Expanding macro 'PRINT_STR' to 'print ( # Hello) ; ptr= nullptr ' + message + Expanding macro 'PRINT_STR' to 'print ( # Hello) ; ptr= nullptr ' + + + kindevent + location + + line274 + col3 + file0 + + ranges + + + + line274 + col3 + file0 + + + line274 + col23 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line275 + col3 + file0 + + + line275 + col3 + file0 + + + end + + + line275 + col8 + file0 + + + line275 + col8 + file0 + + + + + + + kindevent + location + + line275 + col8 + file0 + + ranges + + + + line275 + col4 + file0 + + + line275 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_contexte6947ee72df70243a3b4c9e9eaed0888 + issue_context_kindfunction + issue_contexthashOperatorTest + issue_hash_function_offset3 + location + + line275 + col8 + file0 + + ExecutedLines + + 0 + + 272 + 273 + 274 + 275 + + + + + files + + /home/eumakri/Documents/2codechecker_dev_env/llvm/tools/clang/test/Analysis/plist-macros-with-expansion.cpp + + + \ No newline at end of file Index: test/Analysis/plist-macros-with-expansion.cpp =================================================================== --- /dev/null +++ test/Analysis/plist-macros-with-expansion.cpp @@ -0,0 +1,279 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s +// +// RUN: %clang_analyze_cc1 -analyzer-checker=core %s \ +// RUN: -analyzer-output=plist -o %t.plist \ +// RUN: -analyzer-config expand-macros=true +// +// Check the actual plist output. +// RUN: cat %t.plist | %diff_plist \ +// RUN: %S/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist +// +// Check the macro expansions from the plist output here, to make the test more +// understandable. +// RUN: FileCheck --input-file=%t.plist %s + +void print(const void*); + +//===----------------------------------------------------------------------===// +// Tests for non-function-like macro expansions. +//===----------------------------------------------------------------------===// + +#define SET_PTR_VAR_TO_NULL \ + ptr = 0 + +void nonFunctionLikeMacroTest() { + int *ptr; + SET_PTR_VAR_TO_NULL; + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'SET_PTR_VAR_TO_NULL' to 'ptr = 0 ' + +#define NULL 0 +#define SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO \ + ptr = NULL + +void nonFunctionLikeNestedMacroTest() { + int *ptr; + SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO; + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'SET_PTR_VAR_TO_NULL' to 'ptr = 0 ' + +//===----------------------------------------------------------------------===// +// Tests for function-like macro expansions. +//===----------------------------------------------------------------------===// + +void setToNull(int **vptr) { + *vptr = nullptr; +} + +#define TO_NULL(x) \ + setToNull(x) + +void functionLikeMacroTest() { + int *ptr; + TO_NULL(&ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'TO_NULL' to 'setToNull ( & a ) ' + +#define DOES_NOTHING(x) \ + { \ + int b; \ + b = 5; \ + } \ + print(x) + +#define DEREF(x) \ + DOES_NOTHING(x); \ + *x + +void functionLikeNestedMacroTest() { + int *a; + TO_NULL(&a); + DEREF(a) = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'TO_NULL' to 'setToNull ( & a ) ' + +// CHECK: Expanding macro 'DEREF' to '{ int b ; b = 5 ; } print ( a ) ; * a ' + +//===----------------------------------------------------------------------===// +// Tests for macro arguments containing commas and parantheses. +// +// As of writing these tests, the algorithm expands macro arguments by lexing +// the macro's expansion location, and relies on finding tok::comma and +// tok::l_paren/tok::r_paren. +//===----------------------------------------------------------------------===// + +// Note that this commas, parantheses in strings aren't parsed as tok::comma or +// tok::l_paren/tok::r_paren, but why not test them. + +#define TO_NULL_AND_PRINT(x, str) \ + x = 0; \ + print(str) + +void macroArgContainsCommaInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this , cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'TO_NULL_AND_PRINT' to 'a = 0 ; print ( "Will this , cause a crash?" ) ' + +void macroArgContainsLParenInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this ( cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'TO_NULL_AND_PRINT' to 'a = 0 ; print ( "Will this ( cause a crash?" ) ' + +void macroArgContainsRParenInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this ) cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'TO_NULL_AND_PRINT' to 'a = 0 ; print ( "Will this ) cause a crash?" ) ' + +#define CALL_FUNCTION(funcCall) \ + funcCall + +// Function calls do contain both tok::comma and tok::l_paren/tok::r_paren. + +void macroArgContainsLParenRParenTest() { + int *a; + CALL_FUNCTION(setToNull(&a)); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'CALL_FUNCTION' to 'setToNull ( & a ) ' + +void setToNullAndPrint(int **vptr, const char *str) { + setToNull(vptr); + print(str); +} + +void macroArgContainsCommaLParenRParenTest() { + int *a; + CALL_FUNCTION(setToNullAndPrint(&a, "Hello!")); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'CALL_FUNCTION' to 'setToNullAndPrint ( & a , "Hello!" ) ' + +#define CALL_FUNCTION_WITH_TWO_PARAMS(funcCall, param1, param2) \ + funcCall(param1, param2) + +void macroArgContainsCommaLParenRParenTest2() { + int *a; + CALL_FUNCTION_WITH_TWO_PARAMS(setToNullAndPrint, &a, "Hello!"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'CALL_FUNCTION_WITH_TWO_PARAMS' to 'setToNullAndPrint ( & a , "Hello!" ) ' + +#define CALL_LAMBDA(l) \ + l() + +void commaInBracketsTest() { + int *ptr; + const char str[] = "Hello!"; + // You need to add parantheses around a lambda expression to compile this, + // else the comma in the capture will be parsed as divider of macro args. + CALL_LAMBDA(([&ptr, str] () mutable { TO_NULL(&ptr); })); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'CALL_LAMBDA' to '( [ & ptr , str ] ( ) mutable { TO_NULL ( & ptr ) ; } ) ( ) ' + +#define PASTE_CODE(code) \ + code + +void commaInBracesTest() { + PASTE_CODE({ // expected-warning{{Dereference of null pointer}} + // NOTE: If we were to add a new variable here after a comma, we'd get a + // compilation error, so this test is mainly here to show that this was also + // investigated. + + // int *ptr = nullptr, a; + int *ptr = nullptr; + *ptr = 5; + }) +} + +// CHECK: Expanding macro 'PASTE_CODE' to '{ int * ptr = nullptr ; * ptr = 5 ; } ' + +// Example taken from +// https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html#Macro-Arguments. + +#define POTENTIALLY_EMPTY_PARAM(x, y) \ + x; \ + y = nullptr + +void emptyParamTest() { + int *ptr; + + POTENTIALLY_EMPTY_PARAM(,ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'POTENTIALLY_EMPTY_PARAM' to '; ptr = nullptr ' + +#define NESTED_EMPTY_PARAM(a, b) \ + POTENTIALLY_EMPTY_PARAM(a, b); + + +void nestedEmptyParamTest() { + int *ptr; + + NESTED_EMPTY_PARAM(, ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'NESTED_EMPTY_PARAM' to '; ptr = nullptr ; ' + +#define CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO(func, param) \ + CALL_FUNCTION(func(param)) + +void lParenRParenInNestedMacro() { + int *ptr; + CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO(setToNull, &ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: Expanding macro 'CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO' to 'setToNull ( & ptr ) ' + +//===----------------------------------------------------------------------===// +// Tests for variadic macro arguments. +//===----------------------------------------------------------------------===// + +template +void variadicFunc(Args ...args); + +#define VARIADIC_SET_TO_NULL(ptr, ...) \ + ptr = nullptr; \ + variadicFunc(__VA_ARGS__) + +void variadicMacroArgumentTest() { + int *ptr; + VARIADIC_SET_TO_NULL(ptr, 1, 5, "haha!"); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// TODO: Should correctly display the rest of the parameters. +// CHECK: Expanding macro 'VARIADIC_SET_TO_NULL' to 'ptr = nullptr ; variadicFunc ( 1 ) ' + +//===----------------------------------------------------------------------===// +// Tests for # and ##. +//===----------------------------------------------------------------------===// + +#define DECLARE_FUNC_AND_SET_TO_NULL(funcName, ptr) \ + void generated_##funcName(); \ + ptr = nullptr; + +void hashHashOperatorTest() { + int *ptr; + DECLARE_FUNC_AND_SET_TO_NULL(whatever, ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// TODO: Should expand correctly. +// CHECK: Expanding macro 'DECLARE_FUNC_AND_SET_TO_NULL' to 'void generated_ ## whatever ( ) ; ptr = nullptr ; ' + +#define PRINT_STR(str, ptr) \ + print(#str); \ + ptr = nullptr + +void hashOperatorTest() { + int *ptr; + PRINT_STR(Hello, ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// TODO: Should expand correctly. +// CHECK: Expanding macro 'PRINT_STR' to 'print ( # Hello ) ; ptr = nullptr '