r335964 - [analyzer][UninitializedObjectChecker] Added a NotesAsWarnings flag
Kristof Umann via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 29 04:25:24 PDT 2018
Author: szelethus
Date: Fri Jun 29 04:25:24 2018
New Revision: 335964
URL: http://llvm.org/viewvc/llvm-project?rev=335964&view=rev
Log:
[analyzer][UninitializedObjectChecker] Added a NotesAsWarnings flag
In order to better support consumers of the plist output that don't
parse note entries just yet, a 'NotesAsWarnings' flag was added.
If it's set to true, all notes will be converted to warnings.
Differential Revision: https://reviews.llvm.org/D48285
Added:
cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=335964&r1=335963&r2=335964&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Fri Jun 29 04:25:24 2018
@@ -10,10 +10,19 @@
// This file defines a checker that reports uninitialized fields in objects
// created after a constructor call.
//
-// This checker has an option "Pedantic" (boolean). If its not set or is set to
-// false, the checker won't emit warnings for objects that don't have at least
-// one initialized field. This may be set with
-// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
+// This checker has two options:
+// - "Pedantic" (boolean). If its not set or is set to false, the checker
+// won't emit warnings for objects that don't have at least one initialized
+// field. This may be set with
+//
+// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
+//
+// - "NotesAsWarnings" (boolean). If set to true, the checker will emit a
+// warning for each uninitalized field, as opposed to emitting one warning
+// per constructor call, and listing the uninitialized fields that belongs
+// to it in notes. Defaults to false.
+//
+// `-analyzer-config alpha.cplusplus.UninitializedObject:NotesAsWarnings=true`.
//
//===----------------------------------------------------------------------===//
@@ -32,7 +41,9 @@ class UninitializedObjectChecker : publi
std::unique_ptr<BuiltinBug> BT_uninitField;
public:
- bool IsPedantic; // Will be initialized when registering the checker.
+ // These fields will be initialized when registering the checker.
+ bool IsPedantic;
+ bool ShouldConvertNotesToWarnings;
UninitializedObjectChecker()
: BT_uninitField(new BuiltinBug(this, "Uninitialized fields")) {}
@@ -216,6 +227,9 @@ bool isPrimitiveType(const QualType &T)
return T->isBuiltinType() || T->isEnumeralType();
}
+/// Constructs a note message for a given FieldChainInfo object.
+void printNoteMessage(llvm::raw_ostream &Out, const FieldChainInfo &Chain);
+
} // end of anonymous namespace
//===----------------------------------------------------------------------===//
@@ -264,6 +278,23 @@ void UninitializedObjectChecker::checkEn
LocUsedForUniqueing = PathDiagnosticLocation::createBegin(
CallSite, Context.getSourceManager(), Node->getLocationContext());
+ // For Plist consumers that don't support notes just yet, we'll convert notes
+ // to warnings.
+ if (ShouldConvertNotesToWarnings) {
+ for (const auto &Chain : UninitFields) {
+ SmallString<100> WarningBuf;
+ llvm::raw_svector_ostream WarningOS(WarningBuf);
+
+ printNoteMessage(WarningOS, Chain);
+
+ auto Report = llvm::make_unique<BugReport>(
+ *BT_uninitField, WarningOS.str(), Node, LocUsedForUniqueing,
+ Node->getLocationContext()->getDecl());
+ Context.emitReport(std::move(Report));
+ }
+ return;
+ }
+
SmallString<100> WarningBuf;
llvm::raw_svector_ostream WarningOS(WarningBuf);
WarningOS << UninitFields.size() << " uninitialized field"
@@ -274,29 +305,16 @@ void UninitializedObjectChecker::checkEn
*BT_uninitField, WarningOS.str(), Node, LocUsedForUniqueing,
Node->getLocationContext()->getDecl());
- // TODO: As of now, one warning is emitted per constructor call, and the
- // uninitialized fields are listed in notes. Until there's a better support
- // for notes avaible, a note-less version of this checker should be
- // implemented.
- for (const auto &FieldChain : UninitFields) {
+ for (const auto &Chain : UninitFields) {
SmallString<200> NoteBuf;
llvm::raw_svector_ostream NoteOS(NoteBuf);
- if (FieldChain.isPointer()) {
- if (FieldChain.isDereferenced())
- NoteOS << "uninitialized pointee 'this->";
- else
- NoteOS << "uninitialized pointer 'this->";
- } else
- NoteOS << "uninitialized field 'this->";
- FieldChain.print(NoteOS);
- NoteOS << "'";
+ printNoteMessage(NoteOS, Chain);
Report->addNote(NoteOS.str(),
- PathDiagnosticLocation::create(FieldChain.getEndOfChain(),
+ PathDiagnosticLocation::create(Chain.getEndOfChain(),
Context.getSourceManager()));
}
-
Context.emitReport(std::move(Report));
}
@@ -662,10 +680,24 @@ bool isCalledByConstructor(const Checker
return false;
}
+void printNoteMessage(llvm::raw_ostream &Out, const FieldChainInfo &Chain) {
+ if (Chain.isPointer()) {
+ if (Chain.isDereferenced())
+ Out << "uninitialized pointee 'this->";
+ else
+ Out << "uninitialized pointer 'this->";
+ } else
+ Out << "uninitialized field 'this->";
+ Chain.print(Out);
+ Out << "'";
+}
+
} // end of anonymous namespace
void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) {
auto Chk = Mgr.registerChecker<UninitializedObjectChecker>();
Chk->IsPedantic = Mgr.getAnalyzerOptions().getBooleanOption(
"Pedantic", /*DefaultVal*/ false, Chk);
+ Chk->ShouldConvertNotesToWarnings = Mgr.getAnalyzerOptions().getBooleanOption(
+ "NotesAsWarnings", /*DefaultVal*/ false, Chk);
}
Added: cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp?rev=335964&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp (added)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp Fri Jun 29 04:25:24 2018
@@ -0,0 +1,15 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -analyzer-config alpha.cplusplus.UninitializedObject:NotesAsWarnings=true -std=c++11 -verify %s
+
+class NotesAsWarningsTest {
+ int a;
+ int b;
+ int dontGetFilteredByNonPedanticMode = 0;
+
+public:
+ NotesAsWarningsTest() {} // expected-warning{{uninitialized field 'this->a'}}
+ // expected-warning at -1{{uninitialized field 'this->b'}}
+};
+
+void fNotesAsWarningsTest() {
+ NotesAsWarningsTest();
+}
More information about the cfe-commits
mailing list