forked from OSchip/llvm-project
[analyzer][PlistMacroExpansion] Part 1.: New expand-macros flag
This is the first part of the implementation of the inclusion of macro expansions into the plist output. It adds a new flag that adds a new "macro_expansions" entry to each report that has PathDiagnosticPieces that were expanded from a macro. While there's an entry for each macro expansion, both the name of the macro and what it expands to is missing, and will be implemented in followup patches. Differential Revision: https://reviews.llvm.org/D52742 llvm-svn: 345724
This commit is contained in:
parent
412ed34744
commit
7d6d9eb688
|
@ -307,6 +307,9 @@ private:
|
||||||
/// \sa shouldDisplayNotesAsEvents
|
/// \sa shouldDisplayNotesAsEvents
|
||||||
Optional<bool> DisplayNotesAsEvents;
|
Optional<bool> DisplayNotesAsEvents;
|
||||||
|
|
||||||
|
/// \sa shouldDisplayMacroExpansions
|
||||||
|
Optional<bool> DisplayMacroExpansions;
|
||||||
|
|
||||||
/// \sa shouldAggressivelySimplifyBinaryOperation
|
/// \sa shouldAggressivelySimplifyBinaryOperation
|
||||||
Optional<bool> AggressiveBinaryOperationSimplification;
|
Optional<bool> AggressiveBinaryOperationSimplification;
|
||||||
|
|
||||||
|
@ -693,6 +696,13 @@ public:
|
||||||
/// to false when unset.
|
/// to false when unset.
|
||||||
bool shouldDisplayNotesAsEvents();
|
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
|
/// Returns true if SValBuilder should rearrange comparisons and additive
|
||||||
/// operations of symbolic expressions which consist of a sum of a symbol and
|
/// 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
|
/// a concrete integer into the format where symbols are on the left-hand
|
||||||
|
|
|
@ -464,6 +464,13 @@ bool AnalyzerOptions::shouldDisplayNotesAsEvents() {
|
||||||
return DisplayNotesAsEvents.getValue();
|
return DisplayNotesAsEvents.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AnalyzerOptions::shouldDisplayMacroExpansions() {
|
||||||
|
if (!DisplayMacroExpansions.hasValue())
|
||||||
|
DisplayMacroExpansions =
|
||||||
|
getBooleanOption("expand-macros", /*Default=*/false);
|
||||||
|
return DisplayMacroExpansions.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
bool AnalyzerOptions::shouldAggressivelySimplifyBinaryOperation() {
|
bool AnalyzerOptions::shouldAggressivelySimplifyBinaryOperation() {
|
||||||
if (!AggressiveBinaryOperationSimplification.hasValue())
|
if (!AggressiveBinaryOperationSimplification.hasValue())
|
||||||
AggressiveBinaryOperationSimplification =
|
AggressiveBinaryOperationSimplification =
|
||||||
|
|
|
@ -546,7 +546,8 @@ static void updateStackPiecesWithMessage(PathDiagnosticPiece &P,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
|
static void CompactMacroExpandedPieces(PathPieces &path,
|
||||||
|
const SourceManager& SM);
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<PathDiagnosticControlFlowPiece> generateDiagForSwitchOP(
|
std::shared_ptr<PathDiagnosticControlFlowPiece> generateDiagForSwitchOP(
|
||||||
|
@ -1972,8 +1973,6 @@ static std::unique_ptr<PathDiagnostic> generatePathDiagnosticForConsumer(
|
||||||
PathDiagnosticLocation::createBegin(D, SM));
|
PathDiagnosticLocation::createBegin(D, SM));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AddPathEdges && GenerateDiagnostics)
|
|
||||||
CompactPathDiagnostic(PD->getMutablePieces(), SM);
|
|
||||||
|
|
||||||
// Finally, prune the diagnostic path of uninteresting stuff.
|
// Finally, prune the diagnostic path of uninteresting stuff.
|
||||||
if (!PD->path.empty()) {
|
if (!PD->path.empty()) {
|
||||||
|
@ -2007,6 +2006,10 @@ static std::unique_ptr<PathDiagnostic> generatePathDiagnosticForConsumer(
|
||||||
removeRedundantMsgs(PD->getMutablePieces());
|
removeRedundantMsgs(PD->getMutablePieces());
|
||||||
removeEdgesToDefaultInitializers(PD->getMutablePieces());
|
removeEdgesToDefaultInitializers(PD->getMutablePieces());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GenerateDiagnostics && Opts.shouldDisplayMacroExpansions())
|
||||||
|
CompactMacroExpandedPieces(PD->getMutablePieces(), SM);
|
||||||
|
|
||||||
return PD;
|
return PD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2436,9 +2439,10 @@ bool TrimmedGraph::popNextReportGraph(ReportGraph &GraphWrapper) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
|
/// CompactMacroExpandedPieces - This function postprocesses a PathDiagnostic
|
||||||
/// and collapses PathDiagosticPieces that are expanded by macros.
|
/// object and collapses PathDiagosticPieces that are expanded by macros.
|
||||||
static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
|
static void CompactMacroExpandedPieces(PathPieces &path,
|
||||||
|
const SourceManager& SM) {
|
||||||
using MacroStackTy =
|
using MacroStackTy =
|
||||||
std::vector<
|
std::vector<
|
||||||
std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>>;
|
std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>>;
|
||||||
|
@ -2454,7 +2458,7 @@ static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
|
||||||
|
|
||||||
// Recursively compact calls.
|
// Recursively compact calls.
|
||||||
if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) {
|
if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) {
|
||||||
CompactPathDiagnostic(call->path, SM);
|
CompactMacroExpandedPieces(call->path, SM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the location of the PathDiagnosticPiece.
|
// Get the location of the PathDiagnosticPiece.
|
||||||
|
|
|
@ -72,6 +72,7 @@ class PlistPrinter {
|
||||||
const FIDMap& FM;
|
const FIDMap& FM;
|
||||||
AnalyzerOptions &AnOpts;
|
AnalyzerOptions &AnOpts;
|
||||||
const Preprocessor &PP;
|
const Preprocessor &PP;
|
||||||
|
llvm::SmallVector<const PathDiagnosticMacroPiece *, 0> MacroPieces;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
|
PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
|
||||||
|
@ -86,6 +87,14 @@ public:
|
||||||
(void)AnOpts;
|
(void)AnOpts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Print the expansions of the collected macro pieces.
|
||||||
|
///
|
||||||
|
/// Each time ReportDiag is called on a PathDiagnosticMacroPiece (or, if one
|
||||||
|
/// is found through a call piece, etc), it's subpieces are reported, and the
|
||||||
|
/// piece itself is collected. Call this function after the entire bugpath
|
||||||
|
/// was reported.
|
||||||
|
void ReportMacroExpansions(raw_ostream &o, unsigned indent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ReportPiece(raw_ostream &o, const PathDiagnosticPiece &P,
|
void ReportPiece(raw_ostream &o, const PathDiagnosticPiece &P,
|
||||||
unsigned indent, unsigned depth, bool includeControlFlow,
|
unsigned indent, unsigned depth, bool includeControlFlow,
|
||||||
|
@ -104,7 +113,8 @@ private:
|
||||||
isKeyEvent);
|
isKeyEvent);
|
||||||
break;
|
break;
|
||||||
case PathDiagnosticPiece::Macro:
|
case PathDiagnosticPiece::Macro:
|
||||||
ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), indent, depth);
|
ReportMacroSubPieces(o, cast<PathDiagnosticMacroPiece>(P), indent,
|
||||||
|
depth);
|
||||||
break;
|
break;
|
||||||
case PathDiagnosticPiece::Note:
|
case PathDiagnosticPiece::Note:
|
||||||
ReportNote(o, cast<PathDiagnosticNotePiece>(P), indent);
|
ReportNote(o, cast<PathDiagnosticNotePiece>(P), indent);
|
||||||
|
@ -123,7 +133,7 @@ private:
|
||||||
unsigned indent, unsigned depth, bool isKeyEvent = false);
|
unsigned indent, unsigned depth, bool isKeyEvent = false);
|
||||||
void ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
|
void ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
|
||||||
unsigned indent, unsigned depth);
|
unsigned indent, unsigned depth);
|
||||||
void ReportMacro(raw_ostream &o, const PathDiagnosticMacroPiece& P,
|
void ReportMacroSubPieces(raw_ostream &o, const PathDiagnosticMacroPiece& P,
|
||||||
unsigned indent, unsigned depth);
|
unsigned indent, unsigned depth);
|
||||||
void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
||||||
unsigned indent);
|
unsigned indent);
|
||||||
|
@ -131,6 +141,17 @@ private:
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
|
||||||
|
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 void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
|
static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
|
||||||
AnalyzerOptions &AnOpts,
|
AnalyzerOptions &AnOpts,
|
||||||
const Preprocessor &PP,
|
const Preprocessor &PP,
|
||||||
|
@ -143,6 +164,10 @@ static void printCoverage(const PathDiagnostic *D,
|
||||||
SmallVectorImpl<FileID> &Fids,
|
SmallVectorImpl<FileID> &Fids,
|
||||||
FIDMap &FM,
|
FIDMap &FM,
|
||||||
llvm::raw_fd_ostream &o);
|
llvm::raw_fd_ostream &o);
|
||||||
|
|
||||||
|
static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
|
||||||
|
const Preprocessor &PP);
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Methods of PlistPrinter.
|
// Methods of PlistPrinter.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -299,16 +324,52 @@ void PlistPrinter::ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
|
||||||
ReportPiece(o, *callExit, indent, depth, /*includeControlFlow*/ true);
|
ReportPiece(o, *callExit, indent, depth, /*includeControlFlow*/ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlistPrinter::ReportMacro(raw_ostream &o,
|
void PlistPrinter::ReportMacroSubPieces(raw_ostream &o,
|
||||||
const PathDiagnosticMacroPiece& P,
|
const PathDiagnosticMacroPiece& P,
|
||||||
unsigned indent, unsigned depth) {
|
unsigned indent, unsigned depth) {
|
||||||
|
MacroPieces.push_back(&P);
|
||||||
|
|
||||||
for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
|
for (PathPieces::const_iterator I = P.subPieces.begin(),
|
||||||
I!=E; ++I) {
|
E = P.subPieces.end();
|
||||||
|
I != E; ++I) {
|
||||||
ReportPiece(o, **I, indent, depth, /*includeControlFlow*/ false);
|
ReportPiece(o, **I, indent, depth, /*includeControlFlow*/ false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlistPrinter::ReportMacroExpansions(raw_ostream &o, unsigned indent) {
|
||||||
|
|
||||||
|
for (const PathDiagnosticMacroPiece *P : MacroPieces) {
|
||||||
|
const SourceManager &SM = PP.getSourceManager();
|
||||||
|
ExpansionInfo EI = getExpandedMacro(P->getLocation().asLocation(), PP);
|
||||||
|
|
||||||
|
Indent(o, indent) << "<dict>\n";
|
||||||
|
++indent;
|
||||||
|
|
||||||
|
// Output the location.
|
||||||
|
FullSourceLoc L = P->getLocation().asLocation();
|
||||||
|
|
||||||
|
Indent(o, indent) << "<key>location</key>\n";
|
||||||
|
EmitLocation(o, SM, L, FM, indent);
|
||||||
|
|
||||||
|
// Output the ranges (if any).
|
||||||
|
ArrayRef<SourceRange> Ranges = P->getRanges();
|
||||||
|
EmitRanges(o, Ranges, indent);
|
||||||
|
|
||||||
|
// Output the macro name.
|
||||||
|
Indent(o, indent) << "<key>name</key>";
|
||||||
|
EmitString(o, EI.MacroName) << '\n';
|
||||||
|
|
||||||
|
// Output what it expands into.
|
||||||
|
Indent(o, indent) << "<key>expansion</key>";
|
||||||
|
EmitString(o, EI.Expansion) << '\n';
|
||||||
|
|
||||||
|
// Finish up.
|
||||||
|
--indent;
|
||||||
|
Indent(o, indent);
|
||||||
|
o << "</dict>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PlistPrinter::ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
void PlistPrinter::ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
||||||
unsigned indent) {
|
unsigned indent) {
|
||||||
|
|
||||||
|
@ -339,6 +400,12 @@ void PlistPrinter::ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
||||||
// Static function definitions.
|
// Static function definitions.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
|
||||||
|
const Preprocessor &PP) {
|
||||||
|
// TODO: Implement macro expansion.
|
||||||
|
return { "", "" };
|
||||||
|
}
|
||||||
|
|
||||||
/// Print coverage information to output stream {@code o}.
|
/// Print coverage information to output stream {@code o}.
|
||||||
/// May modify the used list of files {@code Fids} by inserting new ones.
|
/// May modify the used list of files {@code Fids} by inserting new ones.
|
||||||
static void printCoverage(const PathDiagnostic *D,
|
static void printCoverage(const PathDiagnostic *D,
|
||||||
|
@ -408,6 +475,14 @@ static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
|
||||||
Printer.ReportDiag(o, **I);
|
Printer.ReportDiag(o, **I);
|
||||||
|
|
||||||
o << " </array>\n";
|
o << " </array>\n";
|
||||||
|
|
||||||
|
if (!AnOpts.shouldDisplayMacroExpansions())
|
||||||
|
return;
|
||||||
|
|
||||||
|
o << " <key>macro_expansions</key>\n"
|
||||||
|
" <array>\n";
|
||||||
|
Printer.ReportMacroExpansions(o, /* indent */ 4);
|
||||||
|
o << " </array>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -0,0 +1,351 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>diagnostics</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>control</string>
|
||||||
|
<key>edges</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>start</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>25</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>25</integer>
|
||||||
|
<key>col</key><integer>5</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>end</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>26</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>26</integer>
|
||||||
|
<key>col</key><integer>21</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>event</string>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>26</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ranges</key>
|
||||||
|
<array>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>26</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>26</integer>
|
||||||
|
<key>col</key><integer>21</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</array>
|
||||||
|
<key>depth</key><integer>0</integer>
|
||||||
|
<key>extended_message</key>
|
||||||
|
<string>Null pointer value stored to 'ptr'</string>
|
||||||
|
<key>message</key>
|
||||||
|
<string>Null pointer value stored to 'ptr'</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>control</string>
|
||||||
|
<key>edges</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>start</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>end</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>event</string>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ranges</key>
|
||||||
|
<array>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>4</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>6</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</array>
|
||||||
|
<key>depth</key><integer>0</integer>
|
||||||
|
<key>extended_message</key>
|
||||||
|
<string>Dereference of null pointer (loaded from variable 'ptr')</string>
|
||||||
|
<key>message</key>
|
||||||
|
<string>Dereference of null pointer (loaded from variable 'ptr')</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>macro_expansions</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>26</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>name</key><string></string>
|
||||||
|
<key>expansion</key><string></string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string>
|
||||||
|
<key>category</key><string>Logic error</string>
|
||||||
|
<key>type</key><string>Dereference of null pointer</string>
|
||||||
|
<key>check_name</key><string>core.NullDereference</string>
|
||||||
|
<!-- This hash is experimental and going to change! -->
|
||||||
|
<key>issue_hash_content_of_line_in_context</key><string>f8fbc46cc5afbb056d92bd3d3d702781</string>
|
||||||
|
<key>issue_context_kind</key><string>function</string>
|
||||||
|
<key>issue_context</key><string>nonFunctionLikeMacroTest</string>
|
||||||
|
<key>issue_hash_function_offset</key><string>3</string>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>27</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ExecutedLines</key>
|
||||||
|
<dict>
|
||||||
|
<key>0</key>
|
||||||
|
<array>
|
||||||
|
<integer>24</integer>
|
||||||
|
<integer>25</integer>
|
||||||
|
<integer>26</integer>
|
||||||
|
<integer>27</integer>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>control</string>
|
||||||
|
<key>edges</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>start</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>38</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>38</integer>
|
||||||
|
<key>col</key><integer>5</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>end</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>39</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>39</integer>
|
||||||
|
<key>col</key><integer>39</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>event</string>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>39</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ranges</key>
|
||||||
|
<array>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>39</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>39</integer>
|
||||||
|
<key>col</key><integer>39</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</array>
|
||||||
|
<key>depth</key><integer>0</integer>
|
||||||
|
<key>extended_message</key>
|
||||||
|
<string>Null pointer value stored to 'ptr'</string>
|
||||||
|
<key>message</key>
|
||||||
|
<string>Null pointer value stored to 'ptr'</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>control</string>
|
||||||
|
<key>edges</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>start</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>end</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>kind</key><string>event</string>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ranges</key>
|
||||||
|
<array>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>4</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>6</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</array>
|
||||||
|
<key>depth</key><integer>0</integer>
|
||||||
|
<key>extended_message</key>
|
||||||
|
<string>Dereference of null pointer (loaded from variable 'ptr')</string>
|
||||||
|
<key>message</key>
|
||||||
|
<string>Dereference of null pointer (loaded from variable 'ptr')</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>macro_expansions</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>39</integer>
|
||||||
|
<key>col</key><integer>3</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>name</key><string></string>
|
||||||
|
<key>expansion</key><string></string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string>
|
||||||
|
<key>category</key><string>Logic error</string>
|
||||||
|
<key>type</key><string>Dereference of null pointer</string>
|
||||||
|
<key>check_name</key><string>core.NullDereference</string>
|
||||||
|
<!-- This hash is experimental and going to change! -->
|
||||||
|
<key>issue_hash_content_of_line_in_context</key><string>d5eba61193b41c27fc7b2705cbd607ba</string>
|
||||||
|
<key>issue_context_kind</key><string>function</string>
|
||||||
|
<key>issue_context</key><string>nonFunctionLikeNestedMacroTest</string>
|
||||||
|
<key>issue_hash_function_offset</key><string>3</string>
|
||||||
|
<key>location</key>
|
||||||
|
<dict>
|
||||||
|
<key>line</key><integer>40</integer>
|
||||||
|
<key>col</key><integer>8</integer>
|
||||||
|
<key>file</key><integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ExecutedLines</key>
|
||||||
|
<dict>
|
||||||
|
<key>0</key>
|
||||||
|
<array>
|
||||||
|
<integer>37</integer>
|
||||||
|
<integer>38</integer>
|
||||||
|
<integer>39</integer>
|
||||||
|
<integer>40</integer>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>files</key>
|
||||||
|
<array>
|
||||||
|
<string>/home/eumakri/Documents/2codechecker_dev_env/llvm/tools/clang/test/Analysis/plist-macros-with-expansion.cpp</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,44 @@
|
||||||
|
// 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: <key>name</key><string></string>
|
||||||
|
// CHECK-NEXT: <key>expansion</key><string></string>
|
||||||
|
|
||||||
|
#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: <key>name</key><string></string>
|
||||||
|
// CHECK-NEXT: <key>expansion</key><string></string>
|
Loading…
Reference in New Issue